前言
最近面试总是被问到前端模块化,即AMD,CMD,CommonJs,还有ES6 Module这些东西之间的差异,对此我也是一知半解,所以我花了一天时间查阅了不少资料,对各种模块化的方式也有了个大概的了解,在这梳理记录一下免得以后又忘记~~
CommonJs
CommonJs规范主要用在服务端,Nodejs,webpack都是基于该规范来实现的
一般使用module.exports
导出(也可以直接exports),require
引入
基本用法
//a.js
var a = 1
function add (a,b) {
return a + b
}
module.exports = {
a,
add
}
// b.js
var util = require('./a')
util.add(1,2)
特点
- 同步加载,按照书写顺序加载
- 有缓存,多次加载会从缓存里读
- 所以代码运行在模块作用域内,不会污染全局作用域
AMD
全称是Asynchronous Module Definition,即异步模块加载。一般常见的是require.js
,所以这里也以require.js
为例,用require.config
指定引用路径等,define
定义模块,require
引入模块
基本用法
//a.js
define(function(){
var a = 1
function add (a,b) {
return a + b
}
return {
a,
add
}
})
// or
// 假如该模块依赖其他模块,则在[]写入模块名字
define(['jquery'],function(){
$('.body').css({color, 'red'})
// ...
})
// b.js
require(['a'], function(a){
console.log(a.add(1,2))
})
特点
- 依赖前置,提前执行。意思是等数组里的模块加载好后才会执行回调函数
CMD
CMD跟AMD很像,区别是引入模块的时机不一样,是Sea.js
推广过程中产生的模块化规范
基本用法
// a.js
define(function(require,exports,module){
var $ = require('jquert.js') //要用到的时候再引入,而AMD则是一开始就引入
$('.body').css({color, 'red'})
function add (a,b) {
return a + b
}
exports.add = add
})
// b.js
seajs.use(['a.js'],function(a){
console.log(a.add(1,2))
})
特点
- 依赖就近,延迟执行 。意思是模块在require的时候才会执行加载
ES6
直接引用es6文档的原文介绍吧
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
使用export
导出,import
导入
基本用法
// a.js
export var a = 1
export function add(a,b){
return a + b
}
// b.js
import { a, add } from './a'
add(1,2)
// 或者使用export default
// a2.js
export default function add(a,b){
return a + b
}
// b2.js
import add from './a2'
add(1,2)
ES6 模块与 CommonJS 模块的差异
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
- CommonJS 模块的
require()
是同步加载模块,ES6 模块的import
命令是异步加载,有一个独立的模块依赖的解析阶段
参考文档:https://es6.ruanyifeng.com/#docs/module-loader
完事~