node.js 中开启 es modules 有两种可靠方式:一是 package.json 设置 "type": "module"(推荐,需 node.js ≥14.13.0),二是使用 .mjs 扩展名(需 ≥12.20.0,优先级更高);启用后 require() 不可用,需用 import() 动态加载,json 导入需 assert 声明,cjs 包可自动桥接。

在 Node.js 中开启 ES Modules(ESM)主要有两种可靠方式,取决于你的项目结构和 Node.js 版本。当前(2026 年)已全面稳定支持,不再需要 --experimental-modules 参数,但需注意版本与配置匹配。
方式一:通过 package.json 设置 "type": "module"
这是最常用、最推荐的方式,适用于整个包统一使用 ESM:
- 在项目根目录的 package.json 中添加字段:
"type": "module" - Node.js ≥ 14.13.0(LTS 推荐)即可生效;低于 12.20.0 不支持
- 此后所有
.js文件默认按 ESM 解析,可直接写import/export - 无需改后缀名,
index.js、utils.js等都自动启用 ESM
方式二:使用 .mjs 文件扩展名
适合混用场景或不想改动 package.json 的轻量项目:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 将文件保存为
.mjs(如main.mjs、lib.mjs) - Node.js ≥ 12.20.0 即可直接运行:
node main.mjs - 该方式优先级高于
"type"字段 —— 即使 package.json 是"commonjs",.mjs仍按 ESM 执行 -
.cjs文件则始终按 CommonJS 执行,可用于明确隔离 CJS 逻辑
关键注意事项
开启后行为变化明显,需同步调整代码习惯:
-
require()在顶层作用域不可用,动态加载改用await import('./xxx.js') - 不能在同一文件中混用
require()和export(语法错误) - 导入 JSON 需显式声明:
import data from './config.json' assert { type: 'json' };(Node.js ≥ 16.14.0) - 第三方 CJS 包(如 lodash)仍可正常
import _ from 'lodash',Node.js 自动桥接 - monorepo 中每个子包需各自声明
"type": "module",父包设置不继承
验证是否生效
运行时若出现以下错误,说明 ESM 未正确启用:
-
SyntaxError: Cannot use import statement outside a module→ 检查 package.json 是否漏设或拼错"type" -
ERR_REQUIRE_ESM→ 尝试用require()加载了 ESM 文件,应改用import() - 命令行执行
node index.js报错但node index.mjs正常 → 说明"type": "module"未生效或不在当前工作目录的 package.json 中
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










