发布时间:
在 JavaScript 中,模块系统是管理代码依赖和组织大型应用的重要方式。目前主要有三种主流的模块规范:CommonJS、AMD 和 ES 模块(ESM)。它们各有特点,适用于不同的场景。
1. CommonJS 模块 #
定义:CommonJS 是 Node.js 采用的模块规范,主要用于服务器端。
特点:
- 同步加载模块
- 运行时加载
- 模块在首次加载时执行,之后会缓存结果
- 通过
require()
导入,module.exports
或exports
导出
优点:
- 语法简单直观
- 适合服务器端开发,模块加载不会造成性能问题
- 缓存机制提高性能
缺点:
- 同步加载不适合浏览器环境(会阻塞页面渲染)
- 无法在编译时做静态分析
示例:
// math.js - 导出模块
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
module.exports = {
add,
multiply
};
// 或者使用 exports
exports.divide = function(a, b) {
return a / b;
};
// app.js - 导入模块
const math = require('./math.js');
console.log(math.add(2, 3)); // 5
console.log(math.multiply(2, 3)); // 6
2. AMD 模块 #
定义:AMD(Asynchronous Module Definition,异步模块定义)是为浏览器环境设计的模块规范。
特点:
- 异步加载模块
- 支持依赖前置声明
- 通过
define()
定义模块,require()
加载模块
优点:
- 适合浏览器环境,不会阻塞页面渲染
- 可以并行加载多个模块
缺点:
- 语法相对复杂
- 现在使用较少,逐渐被 ES 模块替代
示例:
// math.js - 定义模块
define([], function() {
return {
add: function(a, b) {
return a + b;
},
multiply: function(a, b) {
return a * b;
}
};
});
// 有依赖的模块
define(['./math'], function(math) {
return {
calculateTotal: function(price, quantity) {
return math.multiply(price, quantity);
}
};
});
// 加载模块
require(['./math'], function(math) {
console.log(math.add(2, 3)); // 5
});
3. ES 模块(ESM) #
定义:ES 模块是 ECMAScript 标准定义的模块系统,现在浏览器和 Node.js 都支持。
特点:
- 静态加载(编译时确定依赖)
- 支持异步和同步加载
- 通过
import
导入,export
导出 - 自动采用严格模式
优点:
- 标准规范,浏览器原生支持
- 静态分析支持,有利于 tree-shaking 优化
- 支持命名导出和默认导出
- 同时适用于浏览器和服务器环境
缺点:
- 浏览器中使用需要设置
type="module"
- 与 CommonJS 存在一些互操作复杂性
示例:
// math.js - 导出模块
export function add(a, b) {
return a + b;
}
export const multiply = (a, b) => a * b;
// 默认导出
export default function divide(a, b) {
return a / b;
}
// app.js - 导入模块
import divide, { add, multiply } from './math.js';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
console.log(divide(6, 2)); // 3
// 导入整个模块
import * as math from './math.js';
console.log(math.add(2, 3)); // 5
在 HTML 中使用:
<script type="module" src="app.js"></script>
三者主要区别对比 #
特性 | CommonJS | AMD | ES 模块 |
---|---|---|---|
加载方式 | 同步 | 异步 | 静态(编译时) |
适用环境 | 服务器端(Node.js) | 浏览器端 | 浏览器和服务器端 |
导入语法 | require() |
require() |
import |
导出语法 | module.exports /exports |
define() 返回对象 |
export |
加载时机 | 运行时 | 运行时 | 编译时 |
动态加载 | 支持 | 支持 | 通过 import() 函数支持 |
循环依赖 | 支持(通过缓存) | 支持 | 支持 |
总结 #
- CommonJS 是 Node.js 的标准,适合服务器端开发
- AMD 主要用于浏览器端,支持异步加载
- ES 模块是官方标准,同时支持浏览器和服务器端,是未来的趋势
现在大多数新项目都倾向于使用 ES 模块,特别是在前端开发中,配合 Webpack、Rollup 等构建工具可以获得更好的性能优化。