关于CJS,AMD,CMD,UMD的了解
CommonJS
CommonJS
不完全是一个模块化规范。我们在讨论模块化时候说的CommonJS,其实是说CommonJS中的模块化规范。
CommonJS是一个规范集合,其初衷是为了标准化一套JS在浏览器之外的运行环境。所以,在CommonJS中规范化了File System、Stream、Buffer、Module等。而且,正是因为有了CommonJS这样美好的愿景,影响了后面Node.js的出现。
特点
- 引用模块用require函数;
- 导出模块用exports;
exports是当前文件上下文的一个对象,用来对应挂上某个文件的导出内容,所以可以exports.xxx = ‘xxx’。这里还需要说明的一点是,每一个文件都存在一个module对象,用来指代文件自身。而上面说的exports本质是module对象的一个属性。(我之前写的文章中有详细介绍)输出的东西是值的拷贝,所以,当这个值被输出之后,就算模块内的值发生了变化,被输出的值也不会更新
,多次引入同一个模块,第一引入之后会被缓存,后面的引入都会先在缓存中读取;
同步按顺序加载多个模块
AMD
AMD是Asynchronous Module Define 的缩写。
Async很明显的是异步的意思,也就是这是一种异步加载的模块化规范。
异步加载的原因:CommonJS处理的Node端,是Server端,Server端同步加载无所谓,但是如果在浏览器端的话,同步加载多文件可能会导致白屏等待时间过长
CMD
CMD(Common Module Definition),和AMD的区别主要有两点:
CMD,不完全是异步加载,支持同步require和异步require.async
;
AMD是依赖前置的,就是你在模块头部先声明出模块中要使用的依赖;但是在CMD中,随时需要随时引入
;
UMD
UMD(Universal Module Definition)的出现最初是为了解决大家在代码混用CMD、ADM甚至CommonJS的问题,既然大家混用,那索性就都支持好了。
所以他做的最核心的事情就是,判断当前环境支持那种方式。
ES module
ES module(ESM),是官方的规范。
我们谈到ESM的时候,有这几个关键点是要格外注意的:静态、实现
静态
ESM是静态引入的
静态是编译时,就能确定模块的依赖关系。CommonJS就不是静态的
,它必须到运行的时候才能确定关系,拿到值。
这里说拿到值,但ESM和CJS拿到的值,本质是不一样的。ESM在引入模块时候拿到的是模块的引用,或者说是值的引用
,而CJS拿到的是值的拷贝
,这就会导致一个现象:
实现
ESM是一个规范,规范是需要具体实现的。
例如webpack实现的ESM,以及浏览器实现ESM(script标签中,加上属性type=”module”即可)
参考前端工程