DEBUG.WIKI
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

Node.js 导入 JSON 报 ERR_IMPORT_ATTRIBUTE_MISSING,检查 type 属性

ESM 读取 package.json 报缺少 JSON 类型属性,检查实际产物、with 语法版本与 createRequire 路径。

ESM 程序启动时读取 package.json,报 ERR_IMPORT_ATTRIBUTE_MISSING,错误里还写着 needs an import attribute of "type: json"。此时 JSON 文件可能已经被找到,失败点是导入方式缺少 JSON 类型属性。改相对路径或给目录补 index.js,通常处理不了这个错误。

这种问题也会让命令行工具在建立连接之前退出。例如 Node.js 24.14.0 运行 yuque-mcp 0.1.12 时,启动过程中的 JSON 导入就可能失败;工具尚未启动,先改 MCP 客户端认证或工具调用参数不会触及这个加载阶段。

从实际运行的 JavaScript 确认缺了什么

查看错误指向的 .js 文件,核对它是否仍在使用无属性的 JSON 导入:

import packageJson from '../package.json';

Node 的 JSON ESM 导入要求 type: 'json'。支持 import attributes 的运行环境可以写成:

import packageJson from '../package.json' with { type: 'json' };

console.log(packageJson.version);

这是一段 ESM 示例,JSON 路径相对于当前模块解析。动态导入的写法也要传属性:

const { default: packageJson } = await import('../package.json', {
  with: { type: 'json' },
});

with 语法有版本条件:Node.js 20.10.0、18.20.0 等版本开始切换到 import attributes;旧运行环境不能直接照搬。Node.js 22 已移除旧的 import assertions 支持,因此把 with 换回 assert 也不适合作为新版本的通用修复。

TypeScript 项目需要同时检查编译器、模块输出设置和发布产物。源码带属性,产物没有保留,运行时仍会失败;编译器是否接受该语法也取决于版本和配置。不能仅凭一个项目的构建失败断言 TypeScript 都无法使用它。

只是读取本地包信息时,可以用 createRequire

已有 ESM 工具如果只需要同步读取本地 JSON,可以用 createRequire(),避免把这一处读取交给 JSON ESM 导入:

import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const packageJson = require('../package.json');

createRequire(import.meta.url) 以当前模块的文件 URL 建立 CommonJS 加载入口,再解析相对 JSON 路径。它不是 JSON 内容校验,也不自动解决读取权限、文件缺失或格式错误。不要把这个做法扩展成“所有 ESM 依赖都改成 require”,其他模块仍有各自的加载条件。

yuque-mcp 0.1.13 的正式源码已经用这条路径读取包版本。使用该工具时,可以优先核对锁文件和启动配置是否仍固定在 0.1.12,再按项目方式评估更新。版本标签中存在修正,不代表每个客户端已下载并启动了对应产物;npx 缓存、固定版本和启动器采用的 Node 仍需确认。

恢复要检查到工具真正开始工作

修改前保存导入代码、构建配置与锁文件。重新构建后从原入口启动,确认不再出现 JSON 属性错误,并检查包版本读取结果、服务初始化和后续正常功能。命令行进程不再立即退出,只证明通过了原来的加载失败点。

若同一错误还在,继续沿错误栈找另一处 JSON 导入,而不是反复改同一个文件。若出现语法错误、文件找不到或权限错误,应按新的具体错误处理。撤回时恢复源码与构建配置、依赖组合,不要留下新源码配旧产物的混合状态。