Node.js 中 "Must use import to load ES Module" 错误解决方法
问题描述
在 Node.js 项目中尝试使用 ES6 模块语法时,可能会遇到以下错误:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
这种情况通常发生在以下场景中:
- 使用
import
语句导入 ES 模块 - 文件使用了
export
语法导出内容 - Node.js 未能正确识别模块类型
示例代码:
hello.js
export let myArr = ['hello', 'hi', 'hey'];
index.js
import { myArr } from './hello.js';
console.log(myArr);
解决方案
1. 在 package.json 中设置模块类型
确保你的 package.json
文件包含 "type": "module"
字段:
{
"name": "your-project",
"version": "1.0.0",
"type": "module",
// 其他配置...
}
TIP
从 Node.js 14 开始,ES 模块支持已经成为稳定功能。添加 "type": "module"
后,所有 .js
文件都将被识别为 ES 模块。
2. 使用 .mjs 文件扩展名
另一种方法是将文件扩展名从 .js
改为 .mjs
:
hello.mjs
export let myArr = ['hello', 'hi', 'hey'];
index.mjs
import { myArr } from './hello.mjs';
console.log(myArr);
3. 检查 Node.js 版本
确保你使用的是 Node.js 14 或更高版本:
node --version
对于低于 14 的版本,需要启用实验性模块支持:
node --experimental-modules your.mjs
WARNING
Node.js 12 及更早版本对 ES 模块的支持是实验性的,建议升级到最新 LTS 版本。
4. 处理第三方包兼容性
某些第三方包(如 node-fetch 从 v3 开始)只提供 ES 模块版本。如果遇到兼容性问题:
# 降级到 CommonJS 兼容版本
npm install node-fetch@2
5. 清理并重新安装依赖
有时 Node.js 版本与项目依赖不匹配会导致此问题:
# 删除 node_modules 和 package-lock.json
rm -rf node_modules package-lock.json
# 重新安装依赖
npm install
6. 使用 Babel 转译(传统项目)
对于需要向后兼容的旧项目,可以使用 Babel 转译 ES 模块:
npm install --save-dev @babel/node @babel/core @babel/preset-env
创建 .babelrc
文件:
{
"presets": ["@babel/preset-env"]
}
运行代码:
npx babel-node index.js
DANGER
babel-node
仅适用于开发环境,生产环境应使用正式构建流程。
模块类型对比
特性 | ES 模块 (.mjs 或 type:module) | CommonJS (.js) |
---|---|---|
导入语法 | import { x } from 'y' | const x = require('y') |
导出语法 | export const x = {} | module.exports = x |
文件扩展名 | .mjs 或 .js (有 type:module) | .js 或 .cjs |
动态导入 | 支持 import() | 支持 require() |
顶级 await | 支持 | 不支持 |
常见问题排查
混合使用模块系统:避免在同一项目中混合使用
import
和require()
文件扩展名冲突:确保导入语句中包含完整的文件扩展名
缓存问题:修改模块配置后,重启 Node.js 进程清除缓存
环境变量:检查是否有环境变量影响模块解析
结论
Node.js 中的 "Must use import to load ES Module" 错误通常由模块系统不匹配引起。通过正确配置 package.json
、使用合适的文件扩展名、确保 Node.js 版本兼容性,可以顺利解决这一问题。
对于新项目,建议直接使用 ES 模块语法并在 package.json
中设置 "type": "module"
。对于现有项目,可以根据实际情况选择最适合的迁移策略。