當說到一個應用是模塊化的,意思是說它是由一系列耦合度很低、有明確功能的模塊所組成。鬆耦合經過儘量移除依賴(by removing dependencies)使Apps維護起來更方便;javascript
這裏介紹三種書寫模塊化javascript的方法:AMD, CommonJS, Harmony(proposals for the next version of javascript);php
序:實現模塊化的基本方法就是使用script loaders(推薦RequireJS和curl.js)。從產品發佈的角度來看,使用優化工具(如RequireJS optimizer)將scripts鏈接到一塊是不錯的選擇。頁面加載後的動態腳本加載也可能會有用,RequireJS也支持。html
AMD format的主要目就是爲developer提供javascript模塊化變成的方案;跟CommonJS的主要區別是:AMD是爲browser端而設計;CommonJS面向的是server端;java
AMD和CommonJS的簡單區別(可能不徹底):node
1)scoping:browser中沒法對js代碼進行徹底隔離,只能在function中定義變量使其不會在global中出現,這樣很容易致使錯誤出現: var a=b=0;web
AMD不能很好的解決這個問題。相反,AMD支持將external resource引入local function scope,進而實現local scoping;編程
CJS是乾淨的server端環境,如node,沒有global scope;api
2)Distance:對瀏覽器來講,不少資源都是remote的,雖然資源可能被cache到本地,可請求/得到資源老是費時間的;若是要執行的function在另外一個文件中,咱們就沒法知道這個文件是否已經被load進來或者還要花數秒去得到這個文件;若是不知道function是否已經被定義,那麼就不能擅自調用它;瀏覽器
CJS解決這個問題的方法是:假設全部請求的資源都在本地,或者至少能夠在毫秒級甚至微秒級時間內請求到;app
3)Asynchrony:上邊所說的distance問題形成的直接結果是,須要異步執行task。瀏覽器在單獨線程內執行javascript,若是此線程在等待遠程資源,此時啥也不會執行,用戶感受瀏覽器沒反應了。
解決這個問題的方法是,當資源被準備好了就執行提取初始化操做和請求回調函數操做(callback function);
Node主要經過事件驅動編程模型來實現異步;
簡單地說,CJS同步提取module resource,由於資源在微秒級的時間內能夠到達,不須要異步!
AMD:
// define() is a necessary wrapper. define( // dependencies are specified in advance.指定依賴模塊
['pkgA/modA', 'pkgA/modB', 'pkgZ/modC'], // the module is declared within a definition function. // dependencies are mapped into function parameters. function (modA, modB, modC) { // inside here is the module's code. // the module is exported to the outside world via the // the definition function's returned value. return modC ? modA : modB; } );
CommonJS:
// there is no explicit wrapper, we just write the module's code. // this is not global scope! the scope is limited to this file only. // "free" variables (`require`, `module`, and `exports`) are // declared to help us define our module and fetch resources. // dependencies are specified as needed var modC = require('pkgZ/modC'); // the module is exported by decorating the `exports` free variable. exports.foo = modC ? require('pkgA/modA') : require('pkgA/modB');
___________________________________________AMD____________________________________________
|AMD經過將module定義在definition function裏來處理異步,definition function其實是一個回調函數。 |
|當全部依賴module都加載完畢且起源均可用後,它才被調用; |
|________________________________________________________________________________________|
___________________________________________CJS____________________________________________
|CJS儘量快地執行module代碼,只有須要的時候才load/execute the module dependencies; |
|上邊的示例中,'pkgA/modA'和'pkgB/modB'只加載執行其中一個;當不必加載執行全部modules的狀況下,CJS |
|比AMD效率高; |
|________________________________________________________________________________________|
哪一個更給力?在瀏覽器端,咱們要麼提早提取依賴模塊,要麼同步提取;AMD有兩個plugin,'has.js'和'has!',這倆能夠解決大部分此類問題,但不可能解決全部的狀況;
至於代碼多少,上邊的例子中CJS很明顯少一些;
答案是:neither!兩個都會用到。
1.AMD在browser中使用會有不少好處,究竟有啥好處,這裏。
2.AMD和CJS會共存很長時間,很長!能作的是:
1)用CJS寫server端執行的module;
2)用AMD寫能夠利用其客戶端友好功能的module;