ES Module(import/export)和 CommonJS(require/module.exports)有什么区别?
请比较 ES Module 和 CommonJS 两种模块化方案的核心区别。
回答
古法程序员
| 特性 | ES Module (ESM) | CommonJS (CJS) |
|---|---|---|
| 语法 | import / export | require / module.exports |
| 加载方式 | 静态加载(编译时) | 动态加载(运行时) |
| 输出 | 值的引用(只读动态绑定) | 值的拷贝(缓存结果) |
| 异步/同步 | 异步(支持静态分析) | 同步(Node.js 默认) |
| this | 顶层 this 为 undefined | 顶层 this 为 module.exports |
| 循环依赖 | 支持(基于实时绑定) | 支持但可能获取不完整值 |
| Tree Shaking | ✅ 天然支持 | ❌ 难以静态分析 |
| 条件导入 | ❌ 不能写在条件语句中 | ✅ 可放在 if 中动态 require |
| 文件后缀 | .mjs 或 package.json 配置 "type": "module" | .cjs 或默认 |
ESM 实时绑定示例:
// counter.js
export let count = 0;
export function inc() { count++; }
// main.js
import { count, inc } from './counter.js';
console.log(count); // 0
inc();
console.log(count); // 1(实时绑定)
CJS 值拷贝示例:
// counter.js
let count = 0;
module.exports = { count, inc: () => count++ };
// main.js
const { count, inc } = require('./counter.js');
console.log(count); // 0
inc();
console.log(count); // 0(仍是拷贝值)