CommonJS是node.js的模塊管理的規範,CommonJS寫出的應用能夠具有跨宿主環境執行的能力。CommonJS對模塊的定義十分簡單,主要分爲模塊引用、模塊定義和模塊標識。html
var math =require('math');
在CommonJS規範中,用require()這個方法獲取要引用的模塊。
require函數的規則:前端
require 特性:node
上下文提供了export對象用於導出當前模塊的方法或者變量,而且是惟一的導出的出口。chrome
//demo1.js exports.add = function(){ var sum = 0 ,i=0,args = arguments, l=args.length; while(i< 1){ sum += args[i++]; } return sum; }
在另一個文件中調用npm
var math =require(‘demo1’); exports.incremennt = function(val){ return math.add(val,1) }
模塊標識其實就是傳遞給require函數的參數,它必須是符合小駝峯命名的字符串,或者以. 、 ..開頭的相對路徑,或者絕對路徑。編程
由於有了模塊,咱們就能夠更方便地使用別人的代碼,想要什麼功能,就加載什麼模塊。
可是,這樣作有一個前提,那就是你們必須以一樣的方式編寫模塊,不然你有你的寫法,我有個人寫法,豈不是亂了套!json
基於commonJS規範的nodeJS出來之後,服務端的模塊概念已經造成,很天然地,你們就想要客戶端模塊。並且最好二者可以兼容,一個模塊不用修改,在服務器和瀏覽器均可以運行。可是,因爲一個重大的侷限,使得CommonJS規範不適用於瀏覽器環境。後端
var math = require(‘math’); math.add(2,3);
對服務器端不是一個問題,由於全部的模塊都存放在本地硬盤,能夠同步加載完成,等待時間就是硬盤的讀取時間。可是,對於瀏覽器,這倒是一個大問題,由於模塊都放在服務器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。所以,瀏覽器端的模塊,不能採用"同步加載"(synchronous),只能採用"異步加載"(asynchronous)。這就是AMD規範誕生的背景。CommonJS是主要爲了JS在後端的表現制定的,他是不適合前端的,AMD(異步模塊定義)出現了,它就主要爲前端JS的表現制定規範。AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"。它採用異步方式加載模塊,模塊的加載不影響它後面語句的運行。全部依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成以後,這個回調函數纔會運行。AMD也採用require()語句加載模塊,可是不一樣於CommonJS,它要求兩個參數:數組
require([module],callback);
第一個參數[module],是一個數組,裏面的成員就是要加載的模塊;第二個參數callback,則是加載成功以後的回調函數。若是將前面的代碼改寫成AMD形式,就是下面這樣:瀏覽器
require(['math'],function(math){ math.add(2,3) });
math.add()與math模塊加載不是同步的,瀏覽器不會發生假死。因此很顯然,AMD比較適合瀏覽器環境。目前,主要有兩個Javascript庫實現了AMD規範:require.js和curl.js。
大名遠揚的玉伯寫了seajs,就是遵循他提出的CMD規範,與AMD蠻相近的,不過用起來感受更加方便些,最重要的是中文版。
提到了node的模塊化機制,就不得不提npm,npm是JavaScript的包管理器,它能夠玩成模塊的發佈、安裝和依賴等。藉助npm,node與第三方模塊間造成了一個很好的生態系統。
//demo.js console.log("This is a test");
經過 ‘ node --inspect-brk demo.js ’打開chrome的調試窗口能夠看到實際執行的代碼爲
(function(exports, require, module, __filename, __dirname) { console.log("This is a test"); } );
exports表明模塊的輸出,require表明依賴其它模塊,module表明模塊自己,__filename表明文件路徑,__dirname表明文件夾路徑,2個路徑都是絕對地址。經過編譯後的代碼也能夠看出來每一個文件是一個模塊,有本身的做用域。
文章不少內容參考:js模塊化編程之完全弄懂CommonJS和AMD/CMD!,感謝萬分。