1. 程式人生 > >js-AMD-CMD-依賴區別

js-AMD-CMD-依賴區別

兩者的主要區別如下:

  1. 定位有差異。RequireJS 想成為瀏覽器端的模組載入器,同時也想成為 Rhino / Node 等環境的模組載入器。Sea.js 則專注於 Web 瀏覽器端,同時通過 Node 擴充套件的方式可以很方便跑在 Node 環境中。

  2. 遵循的規範不同。RequireJS 遵循 AMD(非同步模組定義)規範,Sea.js 遵循 CMD (通用模組定義)規範。規範的不同,導致了兩者 API 不同。Sea.js 更貼近 CommonJS Modules/1.1 和 Node Modules 規範。

  3. 推廣理念有差異。RequireJS 在嘗試讓第三方類庫修改自身來支援 RequireJS,目前只有少數社群採納。Sea.js 不強推,採用自主封裝的方式來“海納百川”,目前已有較成熟的封裝策略。

  4. 對開發除錯的支援有差異。Sea.js 非常關注程式碼的開發除錯,有 nocache、debug 等用於除錯的外掛。RequireJS 無這方面的明顯支援。

  5. 外掛機制不同。RequireJS 採取的是在原始碼中預留介面的形式,外掛型別比較單一。Sea.js 採取的是通用事件機制,外掛型別更豐富。

還有不少差異,涉及具體使用方式和原始碼實現,歡迎有興趣者研究並發表看法。

總之,如果說 RequireJS 是 Prototype 類庫的話,則 Sea.js 致力於成為 jQuery 類庫。


我可以說下AMD/CMD的區別以及我的看法:

有必要簡單提一下兩者的主要區別,CMD推崇依賴就近,可以把依賴寫進你的程式碼中的任意一行,例:

define(function(require, exports, module) {
  var a = require('./a')
  a.doSomething()
  var b = require('./b')
  b.doSomething()
})

程式碼在執行時,首先是不知道依賴的,需要遍歷所有的require關鍵字,找出後面的依賴。具體做法是將function toString後,用正則匹配出require關鍵字後面的依賴。顯然,這是一種犧牲效能來換取更多開發便利的方法。

而AMD是依賴前置的,換句話說,在解析和執行當前模組之前,模組作者必須指明當前模組所依賴的模組,表現在require函式的呼叫結構上為:

define(['./a','./b'],function(a,b){
   a.doSomething()
   b.doSomething()
}) 

程式碼在一旦執行到此處,能立即知曉依賴。而無需遍歷整個函式體找到它的依賴,因此效能有所提升,缺點就是開發者必須顯式得指明依賴——這會使得開發工作量變大,比如:當你寫到函式體內部幾百上千行的時候,忽然發現需要增加一個依賴,你不得不回到函式頂端來將這個依賴新增進陣列。

細心的讀者可能發現,到目前位置我討論的AMD和CMD的思想的關於依賴的部分,都只討論的“硬依賴”,也就是執行前肯定需要的依賴,但是這不是全部的情況。有的時候情況是這樣的:
// 函式體內:
if(status){
  a.doSomething()
}

在這個函式體內,可能依賴a,也可能不依賴a,我把這種可能的依賴成為“軟依賴”。對於軟依賴當然可以直接當硬依賴處理,但是這樣不經濟,因為依賴是不一定的,有可能載入了此處的依賴而實際上沒有用上。
對於軟依賴的處理,我推薦依賴前置+回撥函式的實現形式。上面的例子簡單表述如下:
// 函式體內:
if(status){
  async(['a'],function(a){
    a.doSomething()
  })
}

至此可以對由commonJS衍生出來的方案做出總結了。在瀏覽器端來設計模組載入機制,需要考慮依賴的問題。
我們先把依賴分為兩種,“強依賴” —— 肯定需要 和“弱依賴” —— 可能需要。
對於強依賴,如果要效能優先,則考慮參照依賴前置的思想設計你的模組載入器,我個人也更推崇這個方案一些;如果考慮開發成本優先,則考慮按照依賴就近的思想設計你的模組載入器。
對於弱依賴,只需要將弱依賴的部分改寫到回撥函式內即可。

如果現在我要實現一個模組載入器,我會將強依賴前置,弱依賴採用非同步回撥函式的形式,其它的方法我認為都只是語法糖而已,僅此就夠了。

轉自: http://www.zhihu.com/question/21347409#answer-2323656