最初,JavaScript没有import/export 模块的方法。这是个很大的问题,想想如果现在让你把所有代码写在一个文件里,会是什么情况,你愿意去维护么?
然后一些天才想了不同的方法把模块系统引入了JavaScript。最出名的就是这些,CJS,AMD,UMD,ESM
下面来从这些方面一一介绍他们:语法,目的和基本的行为。
CJS
CJS是CommonJS的缩写。它看起来像下图:
- 如果你用过Node.js的话,应该很熟悉这种语法,它就是Node.js的模块系统
- CJS是同步引入模块
- 你可以从一个文件,或者node_modules引入模块,下面两种都可以
- 当使用CJS引入,它会给你一个被引入对象的拷贝
- CJS不被浏览器支持,只能用于后端。如果要在前端使用,必须要先被编译和打包。
AMD
AMD是Asynchronous Module Definition的缩写。示例代码如下:
或者
- AMD是通过异步的方式引入模块的
- AMD是为前端设计的
- AMD语法不如CJS直观
UMD
UMD是Universal Module Definition的缩写,示例代码如下:
- UMD可以在前端和后端同时工作。(估计这就是Universal的由来吧,通用)
- UMD更像是一种配置多个模块系统的模式。
- UMD通常用于打包工具打包后的代码实现,比如Rollup/Webpack之类的
ESM
ESM代表EcmaScript Module。它是JavaScript规范最新提出的模块系统。你肯定见过这种样子的代码:
- ESM被现代浏览器原生支持
- 它语法简单(像CJS),并且是异步导入(像AMD),有它俩共同的优点
- 由于ES6的静态模块结构,它可以做Tree-shakeable。那些打包工具,比如Rollup可以帮你删掉无用代码,这样你就能得到更精简的build,从而提高性能。
- 它还可以被使用在HTML里,比如下面这样
总结
- ESM 是最好的模块系统。它语法简单,原生异步并且可以Tree-shakeable
- UMD 前后端通用,可以作为不支持ESM环境的替代系统。
- CJS 是同步的,可以在后端使用。
- AMD 是异步的,可以在前端使用。