总结
- CommonJS 是 Node.js 中使用的模块化规范,适用于服务端。
- ES6 Module(ESM) 是 ECMAScript 2015 引入的官方模块化标准,适用于浏览器和现代 Node.js 环境。
- 主要区别如下:
- 加载时机不同:CommonJS 是运行时加载,ES6 Module 是编译时加载。
- 输出方式不同:CommonJS 输出值的拷贝,ES6 Module 输出值的引用。
- 使用语法不同:CommonJS 使用
require
和 module.exports
,ES6 Module 使用 import
和 export
。
对比表格
特性 | CommonJS | ES6 Module |
---|
加载时机 | 运行时加载 | 编译时加载 |
输出类型 | 值的拷贝 | 值的引用 |
是否可动态导入 | ✅ 可以(如 require() ) | ✅ 支持动态导入(import() ) |
是否支持静态分析 | ❌ 不支持 | ✅ 支持(利于 Tree-shaking) |
语法 | require / module.exports | import / export |
是否可按需加载 | ❌ 否 | ✅ 可通过 Tree-shaking 实现 |
是否支持异步加载 | ❌ 否 | ✅ 支持(如动态导入) |
示例对比
1. CommonJS 示例
exports.add = function (a, b) {return a + b;
};
module.exports = {add(a, b) {return a + b;},
};
const math = require("./math");
console.log(math.add(1, 2));
2. ES6 Module 示例
export function add(a, b) {return a + b;
}
export default {add(a, b) {return a + b;},
};
import { add } from "./math.js";
console.log(add(1, 2));
import math from "./math.js";
console.log(math.add(1, 2));
加载机制详解
CommonJS:运行时加载
- CommonJS 在代码执行阶段才加载模块。
- 模块输出的是值的拷贝,后续模块内部的值变化不会影响已导出的值。
let count = 0;
function increment() {count++;
}
module.exports = { count, increment };
const { count, increment } = require("./counter");
console.log(count);
increment();
console.log(count);
ES6 Module:编译时加载
- ES6 Module 在代码执行前就已经解析并绑定模块。
- 模块输出的是值的引用,模块内部值变化会影响外部引用。
export let count = 0;
export function increment() {count++;
}
import { count, increment } from "./counter.js";
console.log(count);
increment();
console.log(count);
应用场景对比
场景 | 推荐使用 |
---|
Node.js 项目(旧版本) | ✅ CommonJS |
浏览器项目 | ✅ ES6 Module |
需要 Tree-shaking 优化 | ✅ ES6 Module |
动态导入模块 | ✅ 两者都支持(CommonJS 用 require() ,ES6 用 import() ) |
模块间共享状态 | ✅ ES6 Module(引用机制) |
注意事项
- Node.js 中使用 ES6 Module:需要将文件扩展名改为
.mjs
或在 package.json 中设置 "type": "module"
。 - CommonJS 不支持按需加载:打包工具无法进行 Tree-shaking。
- ES6 Module 更适合现代前端开发:与打包工具(如 Webpack、Rollup)配合更好,支持优化。