参考:
JavaScript模块化-CommonJS、AMD、CMD、UMD、ES6
前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS
在JS早期,使用script标签引入JS,会造成以下问题:
- 加载的时候阻塞网页渲染,引入JS越多,阻塞时间越长。
- 容易污染全局变量。
- js文件存在依赖关系,加载必须有顺序。项目较大时,依赖会错综复杂。
- 引入的JS文件过多,不美观,且不易于管理。
NodeJS诞生之后,它使用CommonJS的模块化规范。从此,js模块化开始快速发展。模块化的开发方式可以提供代码复用率,方便进行代码的管理。通常来说,一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块化规范有CommonJS、AMD、CMD、UMD以及ES6的模块系统。
一、CommonJS规范
NodeJS是CommonJS规范的主要实践者,它有四个重要的环境变量为模块化的实现提供支持:module
、exports
、require
、global
。实际使用时,用module.exports
定义当前模块对外输出的接口(不推荐直接用exports
),用require
加载模块。
二、AMD规范
AMD规范采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
在使用时,需引入require.js,通过require.js实现AMD规范的模块化:用require.config()
指定引用路径等,用definde()
定义模块,用require()
加载模块。
AMD是依赖前置模块。
三、CMD规范
CMD规范同样采用异步方式加载模块,它与AMD很类似,不同点在于:AMD推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行。
在使用时,需引入sea.js,通过sea.js实现CMD规范的模块化:1.使用define()定义模块,使用require()加载模块;2.使用seajs.use加载使用模块。
四、UMD规范
UMD(Universal Module Definition)通用模块定义,为了兼容AMD、CMD和无模块化开发规范。
/** * UMD-Universal Module Definition 通用模块定义 * */ (function (root, factory) { // 判断是否是AMD/CMD if (typeof define === 'function') { define([], factory) } else if (typeof exports === 'object') { // Node CommonJS规范 module.exports = factory() } else { // 浏览器环境 root.someAttr = factory } })(this, function () { let add = function (a, b) { return a + b } return { add, module: 'UMD' } })
五、ES6模块
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。其模块功能主要由两个命令构成:export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能。
六、总结
-
AMD/CMD/CommonJs 是js模块化开发的规范,对应的实现是require.js/sea.js/Node.js。
-
CommonJs 主要针对服务端,AMD/CMD/ES Module主要针对浏览器端,容易混淆的是AMD/CMD。(顺便提一下,针对服务器端和针对浏览器端有什么本质的区别呢?服务器端一般采用同步加载文件,也就是说需要某个模块,服务器端便停下来,等待它加载再执行。这里如果有其他后端语言,如java。而浏览器端要保证效率,需要采用异步加载,这就需要一个预处理,提前将所需要的模块文件并行加载好。)
-
AMD/CMD区别,虽然都是并行加载js文件,但还是有所区别,AMD是预加载,在并行加载js文件同时,还会解析执行该模块(因为还需要执行,所以在加载某个模块前,这个模块的依赖模块需要先加载完成);而CMD是懒加载,虽然会一开始就并行加载js文件,但是不会执行,而是在需要的时候才执行。
-
AMD/CMD的优缺点.一个的优点就是另一个的缺点, 可以对照浏览。
AMD优点:加载快速,尤其遇到多个大文件,因为并行解析,所以同一时间可以解析多个文件。
AMD缺点:并行加载,异步处理,加载顺序不一定,可能会造成一些困扰,甚至为程序埋下大坑。CMD优点:因为只有在使用的时候才会解析执行js文件,因此,每个JS文件的执行顺序在代码中是有体现的,是可控的。
CMD缺点:执行等待时间会叠加。因为每个文件执行时是同步执行(串行执行),因此时间是所有文件解析执行时间之和,尤其在文件较多较大时,这种缺点尤为明显。(PS:重新看这篇文章,发现这里写的不是很准确。确切来说,JS是单线程,所有JS文件执行时间叠加在AMD和CMD中是一样的。但是CMD是使用时执行,没法利用空闲时间,而AMD是文件加载好就执行,往往可以利用一些空闲时间。这么来看,CMD比AMD的优点还是很明显的,毕竟AMD加载好的时候也未必就是JS引擎的空闲时间!)
-
CommonJS 和 ES Module 区别:CommonJS 模块输出的。是一个值的拷贝,ES6 模块输出的是值的引用。
-
如何使用?CommonJs 的话,因为 NodeJS 就是它的实现,所以使用 node 就行,也不用引入其他包。AMD则是通过
<script>
标签引入require.js,CMD则是引入sea.js。 - UMD通用模块定义,为了兼容AMD、CMD和无模块化开发规范。
标签:ES6,CommonJS,模块化,CMD,AMD,js,模块,加载 From: https://www.cnblogs.com/poon5555/p/17174983.html