JavaScript模塊化編程之require.js與sea.js

 

JS中的模塊規範(CommonJS,AMD,CMD)javascript

CommonJS規範-是用在服務器端的(不能用在瀏覽器端),同步的,如nodejs 
AMD規範, CMD規範是用在瀏覽器端的,異步的,如RequireJS SeaJS 前端

AMD 是 RequireJS 在推廣過程當中對模塊定義的規範化產出。
CMD 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。
其中,AMD 先提出(國外),CMD 是根據commonjs和amd基礎上提出的(國內-玉伯)。 java

RequireJS 遵循AMD規範,CMD和AMD基本相同,最大的區別是就CMD是懶加載,AMD是預加載.node

簡單來講,就是SeaJS 屬於懶加載,RequireJS屬於預加載(RequireJS從2.0開始,也改爲能夠延遲執行(根據寫法不一樣,處理方式不經過))。webpack

1.首先原理上的區別程序員

sea.js遵循CMD規範.書寫方式相似node.js的書寫模板代碼.依賴的自動加載,配置的簡潔清晰.說白了就是懶加載.web

在這裏,順便擴展一下預加載和懶加載的優缺點編程

預加載:當第一次訪問時將全部的文件加載出來後端

優勢:第一次訪問完成之後, 再次訪問的速度會很快api

缺點:第一次加載頁面要等待好久.

懶加載:使用的時候纔會加載對應的文件.

優勢:第一次訪問速度相對快點

缺點:再訪問其餘新的模塊時速度會變慢.

 

2.書寫上面的區別

都是用define來定義一個模板.經過require,exports,module三個參數來調動函數.

基本上他們的用法是大同小異的.不過要兩點較大的區別是須要你們去注意的:

1)sea.js使用模塊時用方法seajs.use,而require.js直接用require關鍵字

2)sea.js只使用一個模塊時能夠只傳入一個字符串,可是require傳入的必須是一個數組.

 




CommonJS 

CommonJs 是服務器端模塊的規範,Node.js採用了這個規範。 

2009年,美國程序員Ryan Dahl創造了node.js項目,將javascript語言用於服務器端編程。這標誌"Javascript模塊化編程"正式誕生。由於老實說,在瀏覽器環境下,沒有模塊也不是特別大的問題,畢竟網頁程序的複雜性有限;可是在服務器端,必定要有模塊,與操做系統和其餘應用程序互動,不然根本無法編程。NodeJS是CommonJS規範的實現,webpack 也是以CommonJS的形式來書寫。

基於commonJS規範的nodeJS出來之後,服務端的模塊概念已經造成,很天然地,你們就想要客戶端模塊。並且最好二者可以兼容,一個模塊不用修改,在服務器和瀏覽器均可以運行。可是,因爲一個重大的侷限,使得CommonJS規範不適用於瀏覽器環境。仍是上面的代碼,若是在瀏覽器中運行,會有一個很大的問題,你能看出來嗎?

 

  var math = require('math');

  math.add(2, 3);

 

第二行math.add(2, 3),在第一行require('math')以後運行,所以必須等math.js加載完成。也就是說,若是加載時間很長,整個應用就會停在那裏等。您會注意到 require 是同步的。

這對服務器端不是一個問題,由於全部的模塊都存放在本地硬盤,能夠同步加載完成,等待時間就是硬盤的讀取時間。可是,對於瀏覽器,這倒是一個大問題,由於模塊都放在服務器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。

 

所以,瀏覽器端的模塊,不能採用"同步加載"(synchronous),只能採用"異步加載"(asynchronous)。這就是AMD規範誕生的背景。

 

CommonJS是主要爲了JS在後端的表現制定的,他是不適合前端的,AMD(異步模塊定義)出現了,它就主要爲前端JS的表現制定規範。



根據CommonJS規範,一個單獨的文件就是一個模塊。加載模塊使用require方法,該方法讀取一個文件並執行,最後返回文件內部的exports對象。 

例如: 
// foobar.js 

//私有變量 
var test = 123; 

//公有方法 
function foobar () { 

    this.foo = function () { 
        // do someing ... 
    } 
    this.bar = function () { 
        //do someing ... 
    } 


//exports對象上的方法和變量是公有的 
var foobar = new foobar(); 
exports.foobar = foobar; 

//require方法默認讀取js文件,因此能夠省略js後綴 
var test = require('./boobar').foobar; 

test.bar(); 


CommonJS 加載模塊是同步的,因此只有加載完成才能執行後面的操做。像Node.js主要用於服務器的編程,加載的模塊文件通常都已經存在本地硬盤,因此加載起來比較快,不用考慮異步加載的方式,因此CommonJS規範比較適用。但若是是瀏覽器環境,要從服務器加載模塊,這是就必須採用異步模式。因此就有了 AMD  CMD 解決方案。 


AMD((Asynchromous Module Definition) 

AMD 是 RequireJS 在推廣過程當中對模塊定義的規範化產出 

AMD異步加載模塊。它的模塊支持對象 函數 構造器 字符串 JSON等各類類型的模塊。 

適用AMD規範適用define方法定義模塊。 

//經過數組引入依賴 ,回調函數經過形參傳入依賴 
define(['someModule1', ‘someModule2’], function (someModule1, someModule2) { 

    function foo () { 
        /// someing 
        someModule1.test(); 
    } 

    return {foo: foo} 
}); 
AMD規範容許輸出模塊兼容CommonJS規範,這時define方法以下: 

define(function (require, exports, module) { 
     
    var reqModule = require("./someModule"); 
    requModule.test(); 
     
    exports.asplode = function () { 
        //someing 
    } 
}); 



CMD 

CMD是SeaJS 在推廣過程當中對模塊定義的規範化產出 

CMD和AMD的區別有如下幾點: 

1.對於依賴的模塊AMD是提早執行,CMD是延遲執行。不過RequireJS從2.0開始,也改爲能夠延遲執行(根據寫法不一樣,處理方式不經過)。 

2.CMD推崇依賴就近,AMD推崇依賴前置。 
//AMD 
define(['./a','./b'], function (a, b) { 

    //依賴一開始就寫好 
    a.test(); 
    b.test(); 
}); 

//CMD 
define(function (requie, exports, module) { 
     
    //依賴能夠就近書寫 
    var a = require('./a'); 
    a.test(); 
     
    ... 
    //軟依賴 
    if (status) { 
     
        var b = requie('./b'); 
        b.test(); 
    } 
}); 
雖然 AMD也支持CMD寫法,但依賴前置是官方文檔的默認模塊定義寫法。 

3.AMD的api默認是一個當多個用,CMD嚴格的區分推崇職責單一。例如:AMD裏require分全局的和局部的。CMD裏面沒有全局的 require,提供 seajs.use()來實現模塊系統的加載啓動。CMD裏每一個API都簡單純粹。 

 
AMD 即Asynchronous Module Definition,中文名是異步模塊定義的意思。
CMD 即Common Module Definition通用模塊定義,CMD規範是國內發展出來的,就像AMD有個requireJS,CMD有個瀏覽器的實現SeaJS,SeaJS要解決的問題和requireJS同樣,只不過在模塊定義方式和模塊加載(能夠說運行、解析)時機上有所不一樣 

requireJS主要解決兩個問題

一、多個js文件可能有依賴關係,被依賴的文件須要早於依賴它的文件加載到瀏覽器 二、js加載的時候瀏覽器會中止頁面渲染,加載文件越多,頁面失去響應時間越長 

相關文章
相關標籤/搜索