Published on

浅析前端模块化规范

Authors

Commonjs

Commonjs是以在浏览器环境外构建JavaScript生态系统为目标而产生的项目,比如在服务器或桌面环境中。

// Commonjs是通过module.exports导出对外的变量或接口,
// 通过require()来导入其他模块的输出到当前模块作用域中。

// a.js
module.exports = {a: 'hello'}

// b.js
const b = require(./a);
console.log(b.a)

Commonjs同步加载模块,是服务端模块化的规范Nodejs是基于Commonjs规范实现的。

AMD

AMD是异步定义模块,也是使用require()语句加载模块,但是它需要接收两个参数:

require([module], callback)	//需要加载的模块, 加载完成之后的回调

AMD制定了客户端模块化的规范,Requeirejs基于AMD实现。

UMD

UMDCommonjsAMD的糅合,UMD先判断是否支持Node.js的模块(exports),存在则使用Node.js模块模式;再判断是否支持AMD(define),存在则使用AMD方式加载模块。

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['b'], factory);
  } else if (typeof module === 'object' && module.exports) {
    module.exports = factory(require('b'));
  } else {
    root.returnExports = factory(root.b);
  }
}(typeof self !== 'undefined' ? self : this, function (b) {
  return {};
}));

Commonjs和ES Module的区别

Commonjs模块是对象,是运行时加载,运行时才把模块挂载在exports上,加载模块其实就是查找对象属性;ES Module不是对象,是编译时加载,使用export显示指定输出,再通过import输入。编译时遇到import就会生成一个只读引用,等到运行时就会根据此引用去被加载的模块取值,所以不会加载模块所有的方法。

  • Commonjs模块输出的是值的拷贝;ES Module模块输出的是值的引用
  • Commonjs模块是运行时加载;ES Module模块是编译时输出接口
  • Commonjs模块的require()同步加载依赖;ES Module模块的import命令是异步加载,有一个独立的模块加载的解析阶段。
  • Commonjs的require()不能加载ES Module模块,只能使用import()加载;ES Module的import命令可以加载Commonjs模块,但只能整体加载,不能加载单一的输出项。