前端组件的模块化己发展了很久 这篇文章将对
iife
amd
cmd
cjs
umd
和es6
做一个介绍
IIFE
IIFE
其实在大家应该都用过,只不过没想到还有个名字;IIFE
标准简单说就是执行一个匿名函数, 模块代码放入匿名函数中, 隔离变量作用域,内存释放等问题;1
2
3(function(global){
// code
})(this);
AMD 和 CMD
介绍 AMD
不得不说 RequireJS, 它的出现解决了模块依赖的问题, 使得前端模块化进程加速发展, AMD规范) 其实是RequireJS
出来之后再提出来的.1
2
3
4
5
6
7
8
9
10define('module1','module2'],function(m1,m2){
require(['module3'],function(m3){
})
});
// commonjs 风格:
define(function(require, exports, module){
var m1 = require('module1');
var m2 = require('module2');
})
SeaJS
最初以 就近加载
以及支持 加载 CSS
等特点吸引了很多用户, 并提出了 CMD规范. 但在 RequireJS
也支持这些特性之后, 渐渐淡出;
虽然 SeaJS
没有明显的缺点,但统一标准未尝不是一件好事;1
2
3
4
5
6
7
8
9define(function(require, exports, module) {
//同步加载
var m1 = require('module1');
//异步加载
require.async('module2',function(m2){
})
});
CJS
CJS
其实应该叫 CommonJS
;CommonJS
是nodejs
也就是服务器端广泛使用的模块化机制。该规范的主要内容是,模块必须通过 module.exports
导出对外的变量或接口,通过 require()
来导入其他模块的输出到当前模块作用域中。CommonJS
中的模块加载是同步的, 不适合在浏览器中使用;1
2
3var m1 = require('module1');
//code
module.exports = {}
UMD
UMD
其实不是什么标准, 可以看成是 IIFE
amd
+ cjs
的兼容版.
也就是一个js文件, 可以用 script
标签引用加载, 用 RequireJS
加载, 也可以在 node
当成 CommonJS
模块加载;1
2
3
4
5
6
7
8(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.NAME = factory());
}(this, (function () {
//code
return obj;
})));
如果还想兼容
CMD
判断一下define.cmd
即可;
ES6
ES6
模块其实是 ECMAScript 2015 标准 在语言层面上,实现了模块功能;ES6
而且实现得相当简单,import
引入 export
导出.ES6
模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
现在许多打包工具利用 ES6
的特点, 按需提取代码, 打出的包更加精简.1
2
3
4
5
6//按需加载依赖
import { stat, exists, readFile } from 'fs';
//暴露接口
export default obj; // 默认对外接口
export var foo = 'str'; // 名称为`foo`的对外接口
总结
iife
的方便会让其长期存在amd
在浏览器端还是霸主阶段
在服务端es6
标准化取代cjs
是一种趋势, 但cjs
标准的庞大类库,会让它暂时难以取代.
标准 | 变量问题 | 依赖 | 动态 加载 | 静态分析 |
---|---|---|---|---|
iife | ✔ | ✘ | ✘ | ✘ |
amd | ✔ | ✔ | ✔ | ✘ |
cmd | ✔ | ✔ | ✔ | ✘ |
cjs | ✔ | ✔ | ✘ | ✘ |
es6 | ✔ | ✔ | ✘ | ✔ |