一、js的子產品化規範:
伺服器端:commonjs
浏覽器端:AMD("Asynchronous Module Definition"的縮寫,意思就是"異步子產品定義")
二、為什麼采用AMD
如下代碼
var math = require('math');
math.add(2, 3);
必須等待math.js加載完成,否則會出現加載時間很長現象
三、define
define(id?, dependencies?, factory);
其中:
- id: 子產品辨別,可以省略。
- dependencies: 所依賴的子產品,可以省略。
- factory: 子產品的實作,或者一個JavaScript對象。
以下是使用AMD模式開發的簡單三層結構(基礎庫/UI層/應用層): base.js
define(function() {
return {
mix: function(source, target) {
}
};
});
ui.js
define(['base'], function(base) {
return {
show: function() {
// todo with module base
}
}
});
page.js
define(['data', 'ui'], function(data, ui) {
// init here
});
data.js
define({
users: [],
members: []
});
以上同時示範了define的三種用法, 1,定義無依賴的子產品(base.js) 2,定義有依賴的子產品(ui.js,page.js) 3,定義資料對象子產品(data.js) 細心的會發現,還有一種沒有出現,即具名子產品
define('index', ['data','base'], function(data, base) {
// todo
});
具名子產品多數時候是不推薦的,一般由打包工具合并多個子產品到一個js檔案中時使用。 前面提到dependencies元素的順序和factory一一對應,其實不太嚴謹。AMD開始為擺脫CommonJS的束縛,開創性的提出了自己的子產品風格。但後來又做了妥協,相容了 CommonJS Modules/Wrappings 。即又可以這樣寫
define(function(require, exports, module) {
var base = require('base');
exports.show = function() {
// todo with module base
}
});
不考慮多了一層函數外,格式和Node.js是一樣的:使用require擷取依賴子產品,使用exports導出API。
四、require
require([module], callback);
第一個參數[module],是一個數組,裡面的成員就是要加載的子產品;第二個參數callback,則是加載成功之後的回調函數。如果将前面的代碼改寫成AMD形式,就是下面這樣:
require(['math'], function (math) {
math.add(2, 3);
});
math.add()與math子產品加載不是同步的,浏覽器不會發生假死。是以很顯然,AMD比較适合浏覽器環境。
目前,主要有兩個Javascript庫實作了AMD規範:require.js和curl.js