Modular JavaScript[AMD and CommonJS]入門

原文連接:http://addyosmani.com/writing-modular-js/

Modularity

當說到一個應用是模塊化的,意思是說它是由一系列耦合度很低、有明確功能的模塊所組成。鬆耦合經過儘量移除依賴(by removing dependencies)使Apps維護起來更方便;javascript

這裏介紹三種書寫模塊化javascript的方法:AMD, CommonJS, Harmony(proposals for the next version of javascript);php

序:實現模塊化的基本方法就是使用script loaders(推薦RequireJScurl.js)。從產品發佈的角度來看,使用優化工具(如RequireJS optimizer)將scripts鏈接到一塊是不錯的選擇。頁面加載後的動態腳本加載也可能會有用,RequireJS也支持。html


AMD(a format for writing modular javascript in the browser)

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和CJS的formats

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;

one more thing...看原文。
PS:剛接觸,原文的有些意思可能沒有理解到位,往後再看!

好文Write Modular JavaScript With AMD,CommonJS & ES Harmony: http://addyosmani.com/writing-modular-js/

相關文章
相關標籤/搜索