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