AMD,CMD,CommonJs,UMD讲解

 

一、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 {}; }));
原文地址:https://www.cnblogs.com/lanhuo666/p/10511658.html