1. CommonJS
CommonJS 是 Node.js 默认使用的模块化规范,主要用于服务器端开发。它的特点是同步加载模块
语法:
- 导出模块:使用
module.exports
或exports
- 导入模块:使用
require()
示例:
// math.js (导出模块)
function add(a, b) {
return a + b;
}
module.exports = {
add,
};
// index.js (导入模块)
const math = require('./math');
console.log(math.add(2, 3)); // 输出 5
特点:
- 适用于 Node.js 环境。
- 模块加载是同步的,不适合浏览器的异步加载场景。
- 语法简洁,易于理解。
2. ES Modules (ESM)
ES Modules 是 JavaScript 的官方模块化标准,适合现代前端开发,广泛用于浏览器和 Node.js(Node.js 12+ 已原生支持)。
语法:
- 导出模块:使用
export
或export default
- 导入模块:使用
import
示例:
// math.js (导出模块)
export function add(a, b) {
return a + b;
}
export const PI = 3.14;
// index.js (导入模块)
import { add, PI } from './math.js';
console.log(add(2, 3)); // 输出 5
console.log(PI); // 输出 3.14
默认导出:
// math.js
export default function add(a, b) {
return a + b;
}
// index.js
import add from './math.js';
console.log(add(2, 3));
特点:
- 官方标准,支持浏览器和 Node.js。
- 模块加载是异步的,更适合浏览器环境。
- 语法更现代,支持静态分析(方便构建工具优化)。
3. 如何选择模块化方案?
- Node.js 环境:
- 如果不需要兼容浏览器,优先使用 CommonJS。
- 如果需要使用 ES Modules,可以在
package.json
中设置"type": "module"
。
- 浏览器环境:
- 优先使用 ES Modules,因为它是现代浏览器的标准。
- 混合环境:
- 使用构建工具(如 Webpack、Rollup、Vite)将代码打包为兼容的格式。
4. CommonJS 和 ES Modules 的互操作
在 Node.js 中,可以通过以下方式实现两种模块化方案的互操作:
CommonJS 导入 ES Modules
// math.mjs (ES Modules)
export function add(a, b) {
return a + b;
}
// index.js (CommonJS)
(async () => {
const math = await import('./math.mjs');
console.log(math.add(2, 3));
})();
ES Modules 导入 CommonJS
// math.js (CommonJS)
module.exports = {
add: (a, b) => a + b,
};
// index.mjs (ES Modules)
import math from './math.js';
console.log(math.add(2, 3));
5. 构建工具的支持
现代构建工具(如 Webpack、Rollup、Vite)可以自动处理模块化方案之间的转换和兼容性问题。以下是一些常见的配置:
Webpack
- 默认支持 CommonJS 和 ES Modules。
- 可以通过
babel-loader
将 ES Modules 转换为兼容的格式。
Rollup
- 主要用于打包 ES Modules,支持生成 CommonJS 格式的输出。
Vite
- 基于 ES Modules 的构建工具,支持浏览器直接加载 ES Modules。