模塊化是指在解決某一個復雜問題或者一系列的雜糅問題時,依照一種分類的思維把問題進行系統性的分解以之處理。模塊化是一種處理復雜系統分解為代碼結構更合理,可維護性更高的可管理的模塊的方式。可以想象一個巨大的系統代碼,被整合優化分割成邏輯性很強的模塊時,對於軟件是一種何等意義的存在。對於軟件行業來說:解耦軟件系統的復雜性,使得不管多麼大的系統,也可以將管理,開發,維護變得“有理可循”。
還有一些對於模塊化一些專業的定義為:模塊化是軟件系統的屬性,這個系統被分解為一組高內聚,低耦合的模塊。那麼在理想狀態下我們只需要完成自己部分的核心業務邏輯代碼,其他方面的依賴可以通過直接加載被人已經寫好模塊進行使用即可。
一、AMD
AMD就只有一個接口:define(id?,dependencies?,factory);
它要在聲明模塊的時候制定所有的依賴(dep),並且還要當做形參傳到factory中,像這樣:
復制代碼 代碼如下:
define(['dep1','dep2'],function(dep1,dep2){...});
要是沒什麼依賴,就定義簡單的模塊,下面這樣就可以啦
define(function(){ var exports = {}; exports.method = function(){...}; return exports; });
這裡有define,把東西包裝起來,那Node實現中怎麼沒看到有define關鍵字呢,它也要把東西包裝起來,其實,只是Node隱式包裝了而已..
RequireJS就是實現了AMD規范的
二、CMD
玉伯寫了seajs,就是遵循他提出的CMD規范,比AMD稍微強大點,用起來感覺也方便些
三、AMD與CMD的區別
CMD相當於按需加載,定義一個模塊的時候不需要立即制定依賴模塊,在需要的時候require就可以了,比較方便;而AMD則相反,定義模塊的時候需要制定依賴模塊,並以形參的方式引入factory中
//AMD方式定義模塊
define(['dep1','dep2'],function(dep1,dep2){ //內部只能使用制定的模塊 return function(){}; });
//CMD
define(function(require,exports,module){ //此處如果需要某XX模塊,可以引入 var xx=require('XX'); });
而SEAJS也有use功能也是需要先引入所有依賴的模塊,如
//SEAJS.Use方式 seajs.use(['dep1','dep2'],function(dep1,dep2){ //這裡實現事務 });
四、插件支持
但全球有兩種比較流行的 JavaScript 模塊化體系,一個是 Node 實現的 CommonJS,另外一個是 AMD。很多類庫都同時支持 AMD 和 CommonJS,但是不支持 CMD。或許國內有很多 CMD 模塊,但並沒有在世界上流行起來。
現在比較火的 React 及周邊類庫,就是直接使用 CommonJS 的模塊體系,使用 npm 管理模塊,使用 Browserify 打包輸出模塊。
不久的將來 ES6 中新的模塊化標准,可能就都得遵循新的標准了,什麼AMD、CMD可能到時也不會怎麼用了。
但是目前來說,前端開發沒有用模塊化編程就真的out的了,而目前的模塊化編程,本人還是建議用SEAJS,雖然很多插件需要追加或修改一小塊代碼才能支持。但改過一次就能反復使用,也不會影響其它標准的支持。總體還算是比較方便實用的。
單獨解釋AMD 與 CMD 區別到底在哪裡?
看了以上 AMD,requireJS 與 CMD, seaJS的簡單介紹會有點感覺模糊,總感覺較為相似。因為像 requireJS 其並不是只是純粹的AMD固有思想,其也是有CMD規范的思想,只不過是推薦 AMD規范方式而已, seaJS也是一樣。
下面是玉伯對於 AMD 與 CMD 區別的解釋:
AMD 是 RequireJS 在推廣過程中對模塊定義的規范化產出。
CMD 是 SeaJS 在推廣過程中對模塊定義的規范化產出。
類似的還有 CommonJS Modules/2.0 規范,是 BravoJS 在推廣過程中對模塊定義的規范化產出還有不少??
這些規范的目的都是為了 JavaScript 的模塊化開發,特別是在浏覽器端的。
目前這些規范的實現都能達成浏覽器端模塊化開發的目的。
區別:
1. 對於依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
2. CMD 推崇依賴就近,AMD 推崇依賴前置。看代碼:
// CMD
define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此處略去 100 行 var b = require('./b') // 依賴可以就近書寫 b.doSomething() // ... })
// AMD 默認推薦的是
define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好 a.doSomething() // 此處略去 100 行 b.doSomething() // ... })
雖然 AMD 也支持 CMD 的寫法,同時還支持將 require 作為依賴項傳遞,但 RequireJS 的作者默認是最喜歡上面的寫法,也是官方文檔裡默認的模塊定義寫法。
3. AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。比如 AMD 裡,require 分全局 require 和局部 require,都叫 require。CMD 裡,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啟動。
CMD 裡,每個 API 都簡單純粹。
4. 還有一些細節差異,具體看這個規范的定義就好,就不多說了。