JSON 导入断言类型缺失错误解决方案
问题描述
当在 Node.js 中尝试导入 JSON 文件时,可能会遇到如下错误:
TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]:
Module "file:///Users/xxxxx/code/projects/xxxxx/dist/server/data/countries.json"
needs an import assertion of type "json"
此错误通常发生在 Node.js 17 及以上版本中,当使用 ES 模块语法导入 JSON 文件但未提供必要的类型断言时。
解决方案
方案一:使用 import 断言(推荐)
从 Node.js 17.1.0+ 开始,可以使用 with
关键字进行类型断言:
import countryTable from "./data/countries.json" with { type: "json" };
TIP
with
是新的标准语法,而 assert
关键字在较新版本中已被弃用,但可能仍为兼容性保留。
方案二:使用 createRequire 方法
对于不支持 import 断言的环境,可以使用 Node.js 的 module.createRequire()
:
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const countryTable = require('./data/countries.json');
这种方法适用于 Node.js v12.2.0+ 版本,且不需要启用任何实验性功能。
方案三:手动读取和解析 JSON 文件
如果不希望使用任何实验性功能,可以手动读取和解析 JSON 文件:
import { readFile } from 'fs/promises';
const loadJSON = async (path) => {
const data = await readFile(new URL(path, import.meta.url));
return JSON.parse(data);
};
// 使用方式
const countryTable = await loadJSON('./data/countries.json');
同步版本:
import { readFileSync } from 'fs';
const loadJSONSync = (path) => {
return JSON.parse(readFileSync(new URL(path, import.meta.url), 'utf8'));
};
// 使用方式
const countryTable = loadJSONSync('./data/countries.json');
方案四:使用 CommonJS 语法
如果项目配置允许,可以将文件扩展名改为 .cjs
并使用 CommonJS 语法:
// 将文件重命名为 countries.cjs
const countryTable = require('./data/countries.cjs');
环境配置
Node.js 版本兼容性
不同 Node.js 版本对 JSON 导入的支持:
Node.js 版本 | 支持情况 |
---|---|
< 17.0.0 | 需要使用 --experimental-json-modules 标志 |
17.0.0-17.5.0 | 需要 import 断言 |
17.5.0+ | 支持 with { type: "json" } 语法 |
18.0.0+ | 稳定支持 import 断言 |
启动参数配置
如果必须使用较旧的 Node.js 版本,可以通过命令行标志启用实验性 JSON 模块支持:
node --experimental-json-modules your-script.js
或者在 package.json 中配置:
{
"scripts": {
"start": "node --experimental-json-modules --no-warnings server/server.js"
}
}
常见问题解决
ESLint 错误处理
如果遇到 ESLint 不支持 import 断言语法的问题,可以使用以下方法:
- 更新 ESLint 和相关插件到最新版本
- 暂时禁用相关规则:
// eslint-disable-next-line import/assertions
import data from './data.json' with { type: 'json' };
- 使用文件读取方法替代 import 断言
TypeScript 配置
在 TypeScript 项目中,需要确保 tsconfig.json 配置正确:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true
}
}
最佳实践
- 版本兼容性:根据项目使用的 Node.js 版本选择合适的解决方案
- 代码可读性:优先使用标准的
with
语法,提高代码可读性 - 错误处理:在使用文件读取方法时,添加适当的错误处理机制
- 性能考虑:对于频繁读取的 JSON 文件,考虑缓存解析结果
WARNING
使用实验性功能时,请注意这些功能可能在未来的 Node.js 版本中发生变化或移除。
通过上述方法,您可以有效地解决 ERR_IMPORT_ASSERTION_TYPE_MISSING
错误,并根据项目需求选择最适合的 JSON 文件导入方式。