前端模块化

56 阅读2分钟

Commonjs

Commonjs规范很简单,每个文件是一个模块,module.exports代表这个模块,require引用模块。

CommonJS的实现主要是require时候根据传入的路径找到模块所在文件。

找到文件后用eval包装里面的内容执行,从而得到该文件中定义的模块。

在加载过程中缓存模块,下次再遇到缓存过的模块的引用,就直接返回,否则创建模块并加到缓存列表中,然后返回。

require查找模块的基本过程是:

  1. 判断是否为核心模块,在node本身提供的模块列表中进行查找,如果是就直接返回
  2. 判断是 moduleName是否以/或者./开头,如果是就统一转换成绝对路径进行加载后返回
  3. 如果前两步都没找到,就当做是包模块,到最近的node_moudles来找

特点

  1. 运行时导出对象
  2. 导入会有缓存值,其实就是把模块中的值赋给一个新的变量(值拷贝)(个人理解为快照)
  3. 动态(参数可以是变量,可以根据条件判断是否加载模块)
  4. 引用值可变
  5. 只支持同步

ES6 Module

特点

  1. 编译时导出接口
  2. 导入不会缓存(导入/出的是引用)
  3. 静态,能够分析出依赖关系,所以支持tree-shaking
  4. 只读(适用于服务端)
  5. 支持异步

总结

ES6 module和CommonJS的区别主要有5点

  1. ES6 module是编译时导出接口,CommonJS是运行时导出对象。
  2. ES6 module输出的值的引用,CommonJS输出的是一个值的拷贝。
  3. ES6 module语法是静态的,CommonJS语法是动态的。
  4. ES6 module导入模块的是只读的引用,CommonJS导入的是可变的,是一个普通的变量。
  5. ES6 module支持异步,CommonJS不支持异步。

ES6 module作为新的规范,可以替代之前的AMD、CMD、CommonJS作为浏览器和服务端的通用模块方案。NodeJS在13.2.0版本后已经开始完全支持ES6 module,ES6 module在未来也会实际的模块化标准。