異步模塊定義AMD

全稱爲Asynchronous Module Definition,異步組件(或模塊)定義。AMD是一種機制,使用這種機制,組件和它的依賴就可以實現異步加載。

Define方法

define(id?, dependencies?, factory);

組件ID

組件ID是組件的唯一標識符,在和組件ID一對一的腳本文件(一個腳本文件中只有一個define)中這個ID可以沒有,而且最好沒有。這是因爲組件加載器在請求組件的時候是必須給一個組件ID的,而且需要配置組件ID對應的腳本文件路徑。加載器根據文件路徑就能找到對應的組件腳本文件。所以,加載器可以直接用請求時使用的ID作爲這個組件的ID。這樣的好處是組件轉移到其它項目的時候不需要怕ID衝突而需要修改組件ID,所以,使用define方法定義組件的時候,最好不要設置組件ID。

而且,根據AMD規範,define方法的第一個參數,組件ID必須是頂級或絕對ID,不能是相對ID。這更容易導致組件ID衝突所以,所以,我認爲更不應該在define方法中設置組件ID。

AMD認爲使用define可以幫助靜態分析工具,比如build,我覺得沒這個必要,因爲更多時候在define中組件ID都沒有,分析沒有意義。

根據AMD規範,一個文件中定義多個組件也是可以的,但這就必須給每個define分配一個組件ID。

組件ID格式

注意,在define方法中出現的組件ID必須是頂級或絕對ID。但在require方法或define的依賴數組中出現的組件ID,可以是相對ID(相對於當前組件的ID,而不是相對於組件的路徑),並且完全兼容CommonJS關於組件ID格式的規範

CommonJS關於組件ID的約定:

l  組件ID由'/'分隔的詞組成,每個詞必須是駝峯式寫法,也可以是'.'、'..',用於表示相對關係;

l  組件ID可以有'.js'後綴,也可以沒有'.js'後綴;

舉例:

假如組件'jquery/dialog'對應路徑'jquery/ui/dialog.js',而它依賴'jquery/jquery.js',就需要在'dialog.js'文件中把require寫成這樣:require( '../jquery')或require('../jquery.js')。

依賴數組

也就是第二個數組,依賴數組包含依賴的組件ID,這裏的組件ID允許相對ID。如果沒有定義依賴數組,理論上默認是['require','exports','module'],但這可以取決於factory這個方法的參數個數。如果參數只有一個,那麼依賴數組就可以只是['require'],其它兩個依此類推。

Factory

如果factory是個方法,它的返回值就是該組件對外開發的值。如果factory是個對象,那麼factory就是對外開放的值。

Define.amd

這個屬性是個object,有這個屬性就表示這個全局的define方法符合AMD規範。至於amd有什麼屬性,AMD沒有規定,可以根據情況自己寫。

Require方法

AMD對於require方法的要求比define低,組件加載器可以隨意發揮,只要保證能正常工作即可。比如requirejs的require方法就可以一次要求多個組件,而根據CommonJS規範的組件加載器一次只能要求一個組件。

CommonJS

根據CommonJS的指導,CommonJS是沒有define方法的,依賴完全通過require('module-id')獲取。好在在瀏覽器中,Function對象有一個toString()方法,可以把方法轉換成文本格式。通過在文本中搜索require('module-id')就可以獲取所有依賴。缺點就是這樣就失去了根據條件加載依賴的能力,而是一股腦全部加載。

AMD通過define方法聲明模塊,CommonJS是沒有define方法的,所以AMD和CommonJS是兩回事。但是,根據define的第二個參數的要求,可以看出,AMD的組件同樣可以有require、exports、module這三個變量,因此,把CommonJS組件的代碼拷貝到define方法中,大部分代碼不用修改就可以用的,這點還是比較方便。

注意:Opera手機平臺的Function對象沒有toString()方法,因此CommonJS格式的腳本在這個平臺上可以不能正常運行。

發佈了157 篇原創文章 · 獲贊 165 · 訪問量 115萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章