seajs使用說明

seajs是淘寶的前UED玉伯寫的,可以在http://seajs.org/docs/看到更全面的說明

在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD(Common Module Definition) 模塊定義規範。該規範明確了模塊的基本書寫格式和基本交互規則。

在 CMD 規範中,一個模塊就是一個文件。代碼的書寫格式如下:
define(factory);
define是一個全局函數,用來定義模塊

接收factory參數,factory可以是一個函數,也可以是一個對象或者字符串。

factory爲對象或者字符串時表示該模塊的接口就是該對象或者字符串,

eg:

define({"foo":"bar"})(對象接口)
   define("I'm a templete.My name is {{name}}.")(字符串接口)


factory爲函數時,表示是模塊的構造方法,執行該構造方法得到該模塊對外提供的接口。factory方法在執行時,默認會傳入三個參數:require、exports、module:
define(function(require,exports,module){//模塊代碼
})
define也可以接受兩個以上的參數:

define(id,deps,factory)(id 表示模塊標識,數組deps表示模塊依賴,他們可以省略,省略的時候可以通過構建工具自動生成。帶 id 和 deps 參數的 define 用法不屬於 CMD 規範,而屬於 Modules/Transport 規範。)

define.cmd:一個空對象,可用來判斷當前頁面是否有cmd模塊加載器:

if (typeof define === "function" && define.cmd) {
  // 有 Sea.js 等 CMD 模塊加載器存在}
}
require是factory函數的第一個參數,它是一個函數,接受模塊標識作爲其唯一參數,用來獲取其他模塊提供的接口,require不能被修改,只有這一種唯一的寫法,require的參數必須是字符串直接量:
define(function(require,exports){
var a=require("./a");//獲取模塊a的接口
a.doSomething();//調用模塊a的方法
})
有時需要加載動態依賴,這時可以加一個判斷,

if (todayIsWeekend)
  require("play");
else
  require("work");

但是從靜態文件的角度來看,這個模塊同時依賴play和work這兩個模塊,可以使用require.async來進行條件加載。

require.async用於在模塊內部異步加載模塊,並在加載完成後執行指定回調函數,回調函數可以缺省:

define(function(require,exports){
//異步加載一個模塊
require.async("./b",function(b){
b.doSomething();
});
require.async(["./c","./d"],function(c,d){
//異步加載多個模塊
c.doSomething();
d.doSomething();
});
})

小結:require是同步執行的,require.async 則是異步回調執行。require.async 一般用來加載可延遲異步加載的模塊。

require.resolve(id):

使用模塊系統內部的路徑解析機制來解析並返回模塊路徑。該函數不會加載模塊,只會返回解析後的絕對路徑。這可以用來獲取模塊路徑,一般用在插件環境可能需要動態拼接模塊路徑的情況下。

exports是一個對象,用來提供模塊對外的接口:

define(function(require,exports){

exports.foo="foo";//對外提供foo屬性

exports.doSomething=function(){}//對外提供doSomething方法

})


除了給exports對象增加成員,還可以通過return直接向外提供模塊接口:

define(function(require){
return {
"foo":"foo",
doSomething:function(){}
}
})


如果return語句是代碼中的唯一代碼,也可以直接寫成:

define({
"foo":"foo",
doSomething:function(){}
})


上面這種格式很適合定義jsonp模塊。

下面這種寫法不正確:

define(function(require, exports) {

  // 錯誤用法!!!
  exports = {
    foo: 'bar',
    doSomething: function() {};
  };

});
正確的寫法應該是:

define(function(require, exports,module) {
  module.exports = {
    foo: 'bar',
    doSomething: function() {};
  };
});

exports僅僅是module.exports的一個引用,在factory內部給exports賦值,並不能改變module.exports的值,不能用來更改模塊接口。

module是一個對象,用來存儲與當前模塊相關聯的一些屬性和方法:

module.id:模塊的唯一標識

module.uri:根據模塊系統的路徑解析規則得到的模塊絕對路徑(一般情況下,沒有在define中手寫id參數的時候,module.id===module.uri)

module.dependencies是一個數組,表示當前模塊的依賴
module.exports:當前模塊對外的接口
傳給factory構造函數的參數exports是module.exports對象的一個引用。只通過exports來提供接口,有時無法滿足開發需求。比如當接口是某個類的實例時,需要通過module.exports來實現:
define(function(require, exports, module) {

  // exports 是 module.exports 的一個引用
  console.log(module.exports === exports); // true

  // 重新給 module.exports 賦值
  module.exports = new SomeClass();

  // exports 不再等於 module.exports
  console.log(module.exports === exports); // false

});
對module.exports的賦值需要同步執行,不能放在回調函數裏面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章