再次梳理AMD、CMD、CommonJS、ES6 Module的区别
前言
回想起之前的一次面试,第一轮面试官问我 AMD 和 CMD 的区别,我只回答说 AMD 是提前加载,CMD 是按需加载。第二轮面试官又问了我 CommonJS 和 ES6 Module 的区别,emmm…,我大致回答说新的比旧的好~~,虽然面试官并没有说什么,不过显然这样的答案并不是有助于面试、有助于自己的技术积累的。
所以有必要进行一次梳理,以便更清晰地了解它们的特点及差异。
AMD
AMD 一开始是 CommonJS 规范中的一个草案,全称是 Asynchronous Module Definition,即异步模块加载机制。后来由该草案的作者以 RequireJS 实现了 AMD 规范,所以一般说 AMD 也是指 RequireJS。
RequireJS 的基本用法
通过define
来定义一个模块,使用require
可以导入定义的模块。
1 | //a.js |
RequireJS 的特点
对于依赖的模块,AMD 推崇依赖前置,提前执行。也就是说,在define
方法里传入的依赖模块 (数组),会在一开始就下载并执行。
CMD
CMD 是 SeaJS 在推广过程中生产的对模块定义的规范,在 Web 浏览器端的模块加载器中,SeaJS 与 RequireJS 并称,SeaJS 作者为阿里的玉伯。
SeaJS 的基本用法
1 | //a.js |
SeaJS 的特点
对于依赖的模块,CMD 推崇依赖就近,延迟执行。也就是说,只有到require
时依赖模块才执行。
CommonJS
CommonJS 规范为 CommonJS 小组所提出,目的是弥补 JavaScript 在服务器端缺少模块化机制,NodeJS、webpack 都是基于该规范来实现的。
CommonJS 的基本用法
1 | //a.js |
CommonJS 的特点
- 所有代码都运行在模块作用域,不会污染全局作用域;
- 模块是同步加载的,即只有加载完成,才能执行后面的操作;
- 模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存;
- CommonJS 输出是值的拷贝 (即,
require
返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值)。
ES6 Module
ES6 Module 是 ES6 中规定的模块体系,相比上面提到的规范, ES6 Module 有更多的优势,有望成为浏览器和服务器通用的模块解决方案。
ES6 Module 的基本用法
1 | //a.js |
ES6 Module 的特点 (对比 CommonJS)
- CommonJS 模块是运行时加载,ES6 Module 是编译时输出接口;
- CommonJS 加载的是整个模块,将所有的接口全部加载进来,ES6 Module 可以单独加载其中的某个接口;
- CommonJS 输出是值的拷贝,ES6 Module 输出的是值的引用,被输出模块的内部的改变会影响引用的改变;
- CommonJS
this
指向当前模块,ES6 Modulethis
指向undefined
;
目前浏览器对 ES6 Module 兼容还不太好,我们平时在 webpack 中使用的export
/import
,会被打包为exports
/require
。
写在后面
这里比较宽泛地把 JavaScript 中的几大模块化规范列举出来,希望借此对 JavaScript 模块化有大致的认识,而未对细节展开具体分析,感兴趣的可以自行探索。
https://juejin.cn/post/6844903983987834888
再次梳理AMD、CMD、CommonJS、ES6 Module的区别
http://example.com/2021/04/02/工程化/再次梳理AMD、CMD、CommonJS、ES6 Module的区别/