AMD CMD

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
CommonJS 是 服务器端模块的规范,Node.js采用了这个规范

AMD CMD_第1张图片
Paste_Image.png

区别:

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
AMD:提前执行(异步加载:依赖先执行)+延迟执行
CMD:延迟执行(运行到需加载,根据顺序执行)
  1. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ... 
})

// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
}) 
虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依
赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也
是官方文档里默认的模块定义写法。

3.AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹


Commonjs

var i = 1;
var max = 30;

module.exports = function () {
  for (i -= 1; i++ < max; ) {
    console.log(i);
  }
  max *= 1.1;
};

module.exports对象,定义了一个函数,该函数就是模块外部与内部通信的桥梁。
加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的module.exports对象。


兼容三者的方案

有人试图实现兼容。也就是自己的代码既能在node上运行,也能在符合amd规范的代码环境中运行。于是产生了umd,其实umd并不算规范,而只能算一种兼容方案,它可以兼容CommonJS和AMD。
兼容amd和cmd

if(typeof define == 'function' && (define.amd != undefined || define.cmd != undefined) {
  define(function() {
    return fun();
  });
}

在requirejs中,一个模块可以如此去定义:

define({});
define(factory);
define(id,dependencies,factor);
define(dependencies,factor)

在seajs中也差不多,但是也有不同之处:

define({});
define(factory);
define(id,dependencies,factory);
define(id,factory);

前面三种都是一样的,但是细节上也有所不同,第一种以对象的方式定义并不能解决我们插件中接口传递的目的,因此不考虑。剩下的就只有两种相同的形式,但是就像前文说到的一样,OMD是为了实现兼容,也就是说它必须作为框架被应用,框架的基础代码具有稳定性,不能让用户改来改去,否则也就失去了规范的意义。而在剩下的两种中,define(id,dependencies,factory)的前两个变量,都需要自己去定义,因此,也被排除。最终也就只有define(factory)这种形式被我们采用。

define(function(){
    return {
        fun1 : function(a,b) {},
        fun2 : function(c,d) {}
    }; // return的结果为一个对象
});

兼容comomjs
当define没有被定义的时候,说明跟sea.js和require.js没有任何关系了,这个时候,我们要检查是否支持node.js。
如果是在node.js环境下运行,那么module和exports是一个由核心库提供的全局变量。因此,只需要将插件提供的接口赋值给module.exports,就完成了当前文件(模块)所提供的接口了。
兼容原生的javascript
当以上情况都不满足的情况下,实际上,你所提供的接口,就是一个函数。你提供了一个fun1的接口,你就可以在其他javascript代码中执行fun1()函数。

!!nodejs深入浅出代码

;(function (name, definition) {
 // 检测上下文环境是否为AMD或CMD
 var hasDefine = typeof define === 'function',
 // 检查上下文环境是否为Node
 hasExports = typeof module !== 'undefined' && module.exports;
 
 if (hasDefine) {
 // AMD环境或CMD环境
 define(definition);
 } else if (hasExports) {
 // 定义为普通Node模块
 module.exports = definition();
 } else {
 // 将模块的执行结果挂在window变量中,在浏览器中this指向window对象
 this[name] = definition();
 }
})('hello', function () {
 var hello = function () {};
 return hello;
});

你可能感兴趣的:(AMD CMD)