1. 简介
ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
CommonJS 和 AMD 模块,都只能在运行时确定这些东西。
比如,CommonJS 模块就是对象,输入时必须查找对象属性。
2. CommonJS 模块
1 | // CommonJS模块 |
上面代码的实质是整体加载 fs 模块(即加载 fs 的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。
这种加载称为运行时加载,因为只有运行时才能得到这个对象,导致完全没办法在编译时做静态优化。
3.ES6 模块
ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入。
1 | // ES6模块 |
上面代码的实质是从 fs 模块加载 3 个方法,其他方法不加载。
这种加载称为编译时加载或者静态加载。
即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。
当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。
ES 模块化的静态特性也带来了局限:
1、import依赖必须在文件顶部;
2、export导出的变量类型严格限制;
3、依赖不可以动态确定。
ES 的 export和 export default要用谁?(用export)
其一 export default导出整体对象,不利于 tree shaking;
其二 export default导出的结果可以随意命名,不利于代码管理;
4.比较 CMD/AMD/CommonJS
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。AMD 推崇依赖前置,CMD 推崇依赖就近。
CommonJS 是同步的(只有加载完成才能执行后面的操作),但是 CMD/AMD 是异步的
webpack 对 CommonJS 、 AMD 、ES6 的语法做了兼容,最终采用的都是 CMD 规范