ES6 模块与 CommonJS 模块的区别
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。(因为 CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。)
- CommonJS 模块的 require()是同步加载模块,ES6 模块的 import 命令是异步加载,有一个独立模块依赖的解析阶段。
ES6 模块输出的是值的引用
1 | // lib.mjs |
CommonJS 模块输出的是一个值的拷贝
1 | // lib.cjs |
注
- 从 Node.js v13.2 版本开始,Node.js 已经默认打开了 ES6 模块支持
- Node.js 要求 ES6 模块采用.mjs 后缀文件名
- commonjs 模块采用.cjs 后缀文件名
循环引用
“循环加载”(circular dependency)指的是,a 脚本的执行依赖 b 脚本,而 b 脚本的执行又依赖 a 脚本。
CommonJS 模块的循环加载
CommonJS 模块的脚本代码在 require 的时候,就会全部执行,一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。
ES6 模块的循环加载
ES6 模块遇到模块加载命令 import 时,不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值,不存在缓存值的问题,而且模块里面的变量,绑定其所在的模块。