主题
模块化规范
随着前端项目的复杂度增加,IIFE 的局限性逐渐显现。开发者开始寻找更正式的模块化解决方案,促成了多个模块化规范的诞生。
时间顺序总览
- CJS:2009 年左右,主要用于服务器端(Node.js)。
- AMD:2010 年左右,主要用于浏览器端,解决异步加载问题。
- CMD:2011-2012 年,主要在中国的前端开发中流行,注重按需加载。
- UMD:2011-2012 年,为了在不同环境中兼容 AMD 和 CJS。
- ESM:2015 年正式引入,成为 ECMAScript 6(ES6)标准的一部分,广泛应用于现代浏览器和 JavaScript 生态系统。
CJS
CJS(CommonJS)是较早的模块化规范之一,主要用于服务器端 JavaScript 环境(如:Node.js)。
CJS 规范采用同步加载模块的方式,这在服务器端非常适用。
特点:
- 同步加载模块。
- 适合服务器端。
require导入模块。exports导出模块。
示例:
js
const math = require('./math')
console.log(math.add(2, 3)) // 5js
module.exports = {
add: function (a, b) {
return a + b
},
}AMD
AMD(Asynchronous Module Definition)规范主要为了解决浏览器端异步加载模块的问题,由 RequireJS 团队提出。AMD 允许在浏览器端异步加载模块,提升页面加载性能。
特点:
- 异步加载模块。
- 适合浏览器端。
require加载模块。define定义模块。
示例:
js
define(['math'], function (math) {
console.log(math.add(2, 3)) // 5
})CMD
CMD(Common Module Definition)规范由阿里巴巴的 Sea.js 团队提出,是 对 AMD 的改进,特别强调按需加载和依赖就近。
特点:
- 按需加载,模块只有在被调用时才加载。
- 依赖就近,模块的依赖可以放在模块内部。
示例:
js
define(function (require, exports, module) {
var math = require('./math')
console.log(math.add(1, 2)) // 3
exports.name = 'CMD Module'
})UMD
UMD(Universal Module Definition)规范旨在统一 CJS 和 AMD 的模块化规范,提供一个能够在多种环境中通用的模块定义方式。UMD 使得模块可以在浏览器端和服务器端无缝运行。
特点:
- 通用性强,兼容 CJS 和 AMD。
- 支持无模块系统的环境,通过全局变量暴露接口。
示例:
js
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory)
} else if (typeof module === 'object' && module.exports) {
module.exports = factory()
} else {
root.myModule = factory()
}
})(this, function () {
return {
name: 'UMD Module',
}
})ESM
ES6(也称为 ECMAScript 2015)标准引入了原生的模块化支持,成为现代 JavaScript 开发的主流选择。ESM采用静态分析的方式,编译时就能确定模块的依赖关系。
特点:
- 原生支持模块化,无需额外工具。
import导入模块。export导出模块。- 编译时支持 静态分析,提升编译优化能力。
示例:
js
import { add } from './math.js'
console.log(add(2, 3)) // 5js
export function add(a, b) {
return a + b
}