| 特性 | CommonJS (CJS) | ES Modules (ESM) |
|---|---|---|
| 语法 | require / module.exports | import / export |
| 加载时机 | 运行时加载 (Runtime) | 编译时输出接口 (Compile-time) |
| 输出结果 | 值的拷贝 (浅拷贝) | 值的引用 (Live Binding) |
| this 指向 | 当前模块 (module.exports) | undefined |
| Tree Shaking | 不支持 | 支持 (静态分析) |
CommonJS: 一旦输出一个值,模块内部的变化就影响不到这个值了(除非是引用类型)。
ESM:
JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个引用,到被加载的那个模块里面去取值。
module.exports 属性),该对象只有在脚本运行完才会生成。所以无法在编译时做 Tree Shaking。import 命令会被 JavaScript 引擎静态分析,优先于模块内的其他内容执行。这使得编译器能够分析出哪些功能没有被使用,从而删除死代码 (Tree Shaking)。undefined。在 Node.js 中:
.mjs 文件总是被视为 ESM。.cjs 文件总是被视为 CommonJS。.js 文件取决于 package.json 中的 "type": "module" 字段。混用陷阱:
import cjs from 'cjs-module' (默认导出)。require ESM (因为 ESM 是异步的,CJS 是同步的),通常需要使用 await import().