Skip to content

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

js
export let myArr = ['hello', 'hi', 'hey'];

index.js

js
import { myArr } from './hello.js';
console.log(myArr);

解决方案

1. 在 package.json 中设置模块类型

确保你的 package.json 文件包含 "type": "module" 字段:

json
{
  "name": "your-project",
  "version": "1.0.0",
  "type": "module",
  // 其他配置...
}

TIP

从 Node.js 14 开始,ES 模块支持已经成为稳定功能。添加 "type": "module" 后,所有 .js 文件都将被识别为 ES 模块。

2. 使用 .mjs 文件扩展名

另一种方法是将文件扩展名从 .js 改为 .mjs

hello.mjs

js
export let myArr = ['hello', 'hi', 'hey'];

index.mjs

js
import { myArr } from './hello.mjs';
console.log(myArr);

3. 检查 Node.js 版本

确保你使用的是 Node.js 14 或更高版本:

bash
node --version

对于低于 14 的版本,需要启用实验性模块支持:

bash
node --experimental-modules your.mjs

WARNING

Node.js 12 及更早版本对 ES 模块的支持是实验性的,建议升级到最新 LTS 版本。

4. 处理第三方包兼容性

某些第三方包(如 node-fetch 从 v3 开始)只提供 ES 模块版本。如果遇到兼容性问题:

bash
# 降级到 CommonJS 兼容版本
npm install node-fetch@2

5. 清理并重新安装依赖

有时 Node.js 版本与项目依赖不匹配会导致此问题:

bash
# 删除 node_modules 和 package-lock.json
rm -rf node_modules package-lock.json

# 重新安装依赖
npm install

6. 使用 Babel 转译(传统项目)

对于需要向后兼容的旧项目,可以使用 Babel 转译 ES 模块:

bash
npm install --save-dev @babel/node @babel/core @babel/preset-env

创建 .babelrc 文件:

json
{
  "presets": ["@babel/preset-env"]
}

运行代码:

bash
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支持不支持

常见问题排查

  1. 混合使用模块系统:避免在同一项目中混合使用 importrequire()

  2. 文件扩展名冲突:确保导入语句中包含完整的文件扩展名

  3. 缓存问题:修改模块配置后,重启 Node.js 进程清除缓存

  4. 环境变量:检查是否有环境变量影响模块解析

结论

Node.js 中的 "Must use import to load ES Module" 错误通常由模块系统不匹配引起。通过正确配置 package.json、使用合适的文件扩展名、确保 Node.js 版本兼容性,可以顺利解决这一问题。

对于新项目,建议直接使用 ES 模块语法并在 package.json 中设置 "type": "module"。对于现有项目,可以根据实际情况选择最适合的迁移策略。