一、CommonJS
CommonJS规范加载模块是同步的,只有加载完成,才能执行后面的操作
CommonJS规范中的module、exports和require
每个文件就是一个模块,有自己的作用域。每个模块内部,module变量代表当前模块,是一个对象,它的exports属性(即module.exports)是对外的接口
module.export属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.export变量。
为了方便,node为每个模块提供一个exports变量,指向module.exports。
let exports = module.exports;
require命令用于加载模块文件
注意:如果一个模块的对外接口就是一个单一的值,不能使用exports输出,只能使用module.exports输出。
CommonJS加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这时就需要采用异步模式。所以就有了AMD和CMD解决方案。
二、AMD和CDM比较
区别:
a.对于依赖的模块,AMD是提前执行(2.0后也可以延迟执行),CMD是延迟执行
b.AMD推崇依赖前置,CMD推崇依赖就近
c.AMD推崇复用接口,CMD推崇单用接口
d.书写规范的差异
//CMD define(function(require, exports, module) { let a = require('./a'); a.doSomething(); ··· let b = require('./b'); // 依赖可以就近书写 b.doSomething(); ... }) // AMD 默认推荐的是 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() ... b.doSomething() ... })
比较模块加载器SeaJS和RequireJS
SeaJS只会在真正需要使用(依赖)模块时才执行该模块,SeaJS是异步加载模块的没错, 但执行模块的顺序也是严格按照模块在代码中出现(require)的顺序, 这样也许更符合逻辑。
RequireJS会先尽早地执行(依赖)模块, 相当于所有的require都被提前了, 而且模块执行的顺序也不一定100%就是先mod1再mod2 。因此执行顺序和你预想的完全不一样。
注意这里说的是执行(真正运行define中的代码)模块, 而非加载(load文件)模块。模块的加载都是并行的, 没有区别,区别在于执行模块的时机,或者说是解析。
三、UMD通用模块规范
兼容了AMD和CommonJS,同时还支持老式的“全局”变量规范模块规范主要进行模块加载。
实现原理
1.先判断是否支持Node.js模块格式(exports是否存在),存在则使用Node.js模块格式。
2.再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。
3.前两个都不存在,则将模块公开到全局(window或global)。
jQuery实现判断方式
// if the module has no dependencies, the above pattern can be simplified to (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory);
} else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { // Just return a value to define the module export. // This example returns an object, but the module // can return a function as the exported value. return {}; }));