1.名词解释
AMD:Asynchronous Modules Definition异步模块定义,提供定义模块及异步加载该模块依赖的机制。
CMD:Common Module Definition 通用模块定义,提供模块定义及按需执行模块javascript
RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范,node.js遵循CommonJS规范。规范的不一样,致使了二者 API 不一样。html
2. 提早执行:提早异步并行加载
优势:尽早执行依赖能够尽早发现错误;缺点:容易产生浪费
3. 延迟执行:延迟按需加载
优势:减小资源浪费 缺点:等待时间长、出错时间延后java
2.1 AMD与CMD代码模式node
AMD代码模式-运行策略jquery
define(['./a', './b'], function(a, b) { //运行至此,a.js和b.js已经下载完成 a模块和b模块已经执行完,直接可用; a.doing(); // 此处省略500行代码 b.doing(); });
CMD代码模式-运行策略npm
define(function(require, exports, module) { var a = require("./a"); //等待a.js下载、执行完 a.doing(); // 此处省略500行代码 var b = require("./b"); //依赖就近书写 b.doing(); });
3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。好比 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每一个 API 都简单纯粹。编程
方案 | 优点 | 劣势 | 特色
AMD | 速度快 | 会浪费资源 | 预先加载全部的依赖,直到使用的时候才执行
CMD | 只有真正须要才加载依赖 | 性能较差 | 直到使用的时候才定义依赖数组
它们除了但愿放在浏览器做为loader也可以放在服务端,提供加载功能。在我看来,AMD擅长在浏览器端、CMD擅长在服务器端。这是由于浏览器加载一个功能不像服务器那么快,有大量的网络消耗。因此一个异步loader是更接地气的。浏览器
或者,干脆使用YUI3的模块机制,在上线前进行压制。把互相依赖的模块压在一个文件中。服务器
---------------------------------------------------------------------------------------------------
每个卓越的思想都有一份朴实的代码实现。因此不管AMD与CMD都要面临如下几个问题:
scriptElement= document.createElement('script'); scriptElement.src = moduleUrl; scriptElement.async = true; scriptElement.onload = function(){.........}; document.head.appendChild(scriptElement);
五、模块加载完毕后,获取依赖项(amd、cmd区别),改变模块status,由statuschange后,检测全部模块的依赖项。
因为requirejs与seajs遵循规范不一样,requirejs在define函数中能够很容易得到当前模块依赖项。而seajs中不须要依赖声明,因此必须作一些特殊处理才可否得到依赖项。方法将factory做toString处理,而后用正则匹配出其中的依赖项,好比出现require(./a),则检测到须要依赖a模块。
同时知足非阻塞和顺序执行就须要须要对代码进行一些预处理,这是因为CMD规范和浏览器环境特色所决定的。
六、若是模块的依赖项彻底加载完毕(amd中须要执行完毕,cmd中只须要文件加载完毕,注意这时候的factory还没有执行,当使用require请求该模块时,factory才会执行,因此在性能上seajs逊于requirejs),执行主模块的factory函数;不然进入步骤3.
AMD规范定义了一个自由变量或者说是全局变量 define 的函数
define( id?, dependencies?, factory );
define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){ export.verb = function(){ return beta.verb(); // or: return require("beta").verb(); } });
define(["alpha"], function( alpha ){ return { verb : function(){ return alpha.verb() + 1 ; } } });
define( { add : function( x, y ){ return x + y ; } } );
局部 与 全局 的require
define( ['require'], function( require ){ // ... } ); or: define( function( require, exports, module ){ // ... } );
require(String) define( function( require ){ var a = require('a'); // 加载模块a } ); require(Array, Function) define( function( require ){ require( ['a', 'b'], function( a,b ){ // 加载模块a b 使用 // 依赖 a b 模块的运行代码 } ); } ); require.toUrl( Url ) define( function( require ){ var temp = require.toUrl('./temp/a.html'); // 加载页面 } );
define({ "foo": "bar" });
define('this is {{data}}.');
define( function(require, exports, module) { // 模块代码 });
define( 'module', ['module1', 'module2'], function( require, exports, module ){ // 模块代码 } );
define(function( require, exports ){ var a = require('./a'); a.doSomething(); });
define( function(require, exports, module) { require.async('.a', function(a){ a.doSomething(); }); });
define(function( require, exports ){ exports.foo = 'bar'; // 向外提供的属性 exports.do = function(){}; // 向外提供的方法 });
define(function( require, exports ){ return{ foo : 'bar', // 向外提供的属性 do : function(){} // 向外提供的方法 } });
define({ foo : 'bar', // 向外提供的属性 do : function(){} // 向外提供的方法 });
define(function( require, exports ){ exports = { foo : 'bar', // 向外提供的属性 do : function(){} // 向外提供的方法 } });
须要这么作
define(function( require, exports, module ){ module.exports = { foo : 'bar', // 向外提供的属性 do : function(){} // 向外提供的方法 } });
// moduleA.js module.exports = function( value ){ return value * 2; }
// moduleB.js var multiplyBy2 = require('./moduleA'); var result = multiplyBy2(4);
require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;
define("module", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; }); require(["module", "../file"], function(module, file) { /* ... */ });
define(function(require, exports, module) { var $ = require('jquery'); var Spinning = require('./spinning'); exports.doSomething = ... module.exports = ... })
转载:https://www.zhihu.com/question/20351507
http://blog.csdn.net/vuturn/article/details/51970567