在ESM时代 由于webpack,rollup等构建工具,处理工具 原本是动态语言的JS变得越来越像静态语言了, 可以更好的支持类型检查,死代码删除等等功能. 甚至在webbapck5中可以支持动态require并执行静态检查的功能(这里不得不佩服webpack的强大)
这里整理了一下老模块化规范CJS 和新模块化规范ESM的优缺点:
CJS优点
CJS是同步加载 通过调用require()函数来访问module.export
在Node中 每个CJS文件都会生成一个module实例对象 导出使用的就是其中的module.export
- 可以支持动态加载 比如在if中加载模块
// 不同的情况加载不同的模块
if(ENV==="dev"){
const fn = require('./aFun.js')
}else {
const fn = require('./bFun.js')
}
ESM优点
因为ESM (import)先有一个构建依赖图的过程 所以在这个过程中可以很方便的进行静态处理
- 构建时可以进行各种静态检查 : 静态类型检查 (比如Ts就使用ESM语法) 变量检查
- 构建时可以消除死代码 treeShakiing
- 因为构建了依赖图 可以更快的查找导入 如果是CJS 需要访问一个对象 并且进行动态属性查找 速度慢
- 可以更方便的支持其他语言 静态的可以进行编译
- 支持循环依赖 子依赖父 父依赖子 (因为是静态)
ESM缺点
不支持动态
- 不能像CJS一样在语句中进行引入
- 不能进行解构 (只是看上去像解构 真正的解构是动态访问对象) 如下:
// 不能在ES6中做这样的事情
import { foo: { bar } } from 'some_module';