IIFE
刀耕火种年代,以自执行的匿名函数创建函数作用域,避免全局变量污染
<script src='a.js' />
// a.js
(function() {
var name = 'remons'
})()
CommonJS
一般用于 Node 环境
模块引入具有缓存机制,第一次引入时,会依次顺序执行模块内容,后续再引用时,则直接使用缓存
const a = require('a.js')
require
简易实现
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// 模块代码在这里,在这个例子中,我们定义了一个函数
function someFunc() {}
exports = someFunc;
// 当代码运行到这里时,exports 不再是 module.exports 的引用,并且当前的
// module 仍旧会导出一个空对象(就像上面声明的默认对象那样)
module.exports = someFunc;
// 当代码运行到这时,当前 module 会导出 someFunc 而不是默认的对象
})(module, module.exports);
return module.exports;
}
当然,缺点也很明显
- 不可用于浏览器环境
- 同步加载,阻塞代码的执行
AMD
require.js
异步加载,依赖前置
// math.js
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});
// index.js
require(['math'], function(math) {
math.add(1, 2);
});
CMD
sea.js
异步加载,依赖就近,按需加载
define(function (requie, exports, module) {
// 依赖就近
var moduleA = require('./a');
moduleA.mehodA();
// 按需加载
if (needModuleB) {
var moduleB = requie('./b');
moduleB.methodB();
}
// 导出数据
exports = {};
});
UMD
兼容 CommonJS、AMD、CMD 等模块方案
ES Module
会对静态代码分析,即在代码编译时进行模块的加载
// index.js
import a from '/a.js';
// a.js
const a = () => {};
export default a;
AMD 和 CMD 差异
- AMD 推崇依赖前置,CMD 推崇依赖就近
- AMD 提前执行(即一开始就会执行),CMD 延迟执行(即执行到 require 时执行)
CommonJS 和 ES Module 差异
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
- CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。