Commonjs
Commonjs规范很简单,每个文件是一个模块,module.exports代表这个模块,require引用模块。
CommonJS的实现主要是require时候根据传入的路径找到模块所在文件。
找到文件后用eval包装里面的内容执行,从而得到该文件中定义的模块。
在加载过程中缓存模块,下次再遇到缓存过的模块的引用,就直接返回,否则创建模块并加到缓存列表中,然后返回。
require查找模块的基本过程是:
- 判断是否为核心模块,在node本身提供的模块列表中进行查找,如果是就直接返回
- 判断是 moduleName是否以/或者./开头,如果是就统一转换成绝对路径进行加载后返回
- 如果前两步都没找到,就当做是包模块,到最近的node_moudles来找
特点
- 运行时导出对象
- 导入会有缓存值,其实就是把模块中的值赋给一个新的变量(值拷贝)(个人理解为快照)
- 动态(参数可以是变量,可以根据条件判断是否加载模块)
- 引用值可变
- 只支持同步
ES6 Module
特点
- 编译时导出接口
- 导入不会缓存(导入/出的是引用)
- 静态,能够分析出依赖关系,所以支持tree-shaking
- 只读(适用于服务端)
- 支持异步
总结
ES6 module和CommonJS的区别主要有5点
- ES6 module是编译时导出接口,CommonJS是运行时导出对象。
- ES6 module输出的值的引用,CommonJS输出的是一个值的拷贝。
- ES6 module语法是静态的,CommonJS语法是动态的。
- ES6 module导入模块的是只读的引用,CommonJS导入的是可变的,是一个普通的变量。
- ES6 module支持异步,CommonJS不支持异步。
ES6 module作为新的规范,可以替代之前的AMD、CMD、CommonJS作为浏览器和服务端的通用模块方案。NodeJS在13.2.0版本后已经开始完全支持ES6 module,ES6 module在未来也会实际的模块化标准。