淺析JS模塊規範:AMD,CMD,CommonJS

from:https://www.jianshu.com/p/09ffac7a3b2cnode

隨着JS模塊化編程的發展,處理模塊之間的依賴關係成爲了維護的關鍵。npm


 
模塊化

AMD,CMD,CommonJS是目前最經常使用的三種模塊化書寫規範。編程

CommonJS

CommonJS規範是誕生比較早的。NodeJS就採用了CommonJS。是這樣加載模塊:json

var clock = require('clock'); clock.start(); 

這種寫法適合服務端,由於在服務器讀取模塊都是在本地磁盤,加載速度很快。可是若是在客戶端,加載模塊的時候有可能出現「假死」情況。好比上面的例子中clock的調用必須等待clock.js請求成功,加載完畢。那麼,能不能異步加載模塊呢?數組

 

一、CommonJs規範的出發點:JS沒有模塊系統、標準庫較少、缺少包管理工具;爲了讓JS能夠在任何地方運行,以達到Java、C#、PHP這些後臺語言具有開發大型應用的能力;緩存

 

二、在CommonJs規範中:服務器

    一個文件就是一個模塊,擁有單獨的做用域;異步

    普通方式定義的變量、函數、對象都屬於該模塊內;模塊化

    經過require來加載模塊;函數

    經過exports和modul.exports來暴露模塊中的內容;

 

三、全部代碼都運行在模塊做用域,不會污染全局做用域;模塊能夠屢次加載,但只會在第一次加載的時候運行一次,而後運行結果就被緩存了,之後再加載,就直接讀取緩存結果;模塊的加載順序,按照代碼的出現順序是同步加載的;

 

四、__dirname表明當前模塊文件所在的文件夾路徑,__filename表明當前模塊文件所在的文件夾路徑+文件名;

 

五、require(同步加載)基本功能:讀取並執行一個JS文件,而後返回該模塊的exports對象,若是沒有發現指定模塊會報錯;

 

六、模塊內的exports:爲了方便,node爲每一個模塊提供一個exports變量,其指向module.exports,至關於在模塊頭部加了這句話:var exports = module.exports,在對外輸出時,能夠給exports對象添加方法,PS:不能直接賦值(由於這樣就切斷了exports和module.exports的聯繫);

 

七、npm root -g:查看npm全局包安裝位置,建議在nvm目錄下新建npm\node_modules目錄,而後設置npm的全局包安裝位置:npm config set prefix "",而後將該路徑添加到環境變量中;

 

八、npm init -y:初始化一個package.json文件,加上-y就會默認生成該文件,無需一步一步填寫;npm docs 包名:查看包的文檔;npm install:安裝package.json中dependencies屬性中全部依賴的包

 

九、因爲npm的服務器是國外的,因此若是你沒有和諧工具是下載不了的,這裏推薦使用淘寶NPM鏡像:http://npm.taobao.org/,與官方NPM的同步頻率目前爲10分鐘一次;安裝命令:npm install -g cnpm --registry=https://registry.npm.taobao.org,安裝包:cnpm install 包名(其它命令基本一致);

 

十、若是你不想下載cnpm,npm還提供了一個鏡像源管理工具:npm install -g nrm,經過:nrm ls,查看鏡像源列表 ,經過:npm use 鏡像源,來切換;

 

十一、NPM的模塊加載機制:

      若是require的是絕對路徑文件,查找不會去遍歷每一個node_modules目錄,其速度最快

  1).從module.paths數組中(由當前執行文件目錄到磁盤根目錄)取出第一個目錄做爲查找基準

  2).直接從目錄中查找該文件,若是存在則結束查找,若是不存在則進行下一條查找

  3).嘗試添加.js、.node、.json後綴以後查找,若是存在文件則結束查找,若是不存在則進行下一條查找

  4).嘗試將require的參數做爲一個包來進行查找,讀取目錄下的package.json文件,取得Main參數指定的文件

  5).嘗試查找該文件,若是存在則結束查找,若是不存在則進行第3條查找

  6).若是繼續失敗,則取出module.paths數組中的下一目錄做爲基準查找,循環第1-5個步驟

  7).若是繼續失敗,循環第1-6個步驟,直到module.paths中的最後一個值

  8).若是繼續失敗,則拋出異常

AMD

AMD,即 (Asynchronous Module Definition),這種規範是異步的加載模塊,requireJs應用了這一規範。先定義全部依賴,而後在加載完成後的回調函數中執行:

require([module], callback); 

用AMD寫上一個模塊:

require(['clock'],function(clock){ clock.start(); }); 

AMD雖然實現了異步加載,可是開始就把全部依賴寫出來是不符合書寫的邏輯順序的,能不能像commonJS那樣用的時候再require,並且還支持異步加載後再執行呢?

CMD

CMD (Common Module Definition), 是seajs推崇的規範,CMD則是依賴就近,用的時候再require。它寫起來是這樣的:

define(function(require, exports, module) { var clock = require('clock'); clock.start(); }); 

AMD和CMD最大的區別是對依賴模塊的執行時機處理不一樣,而不是加載的時機或者方式不一樣,兩者皆爲異步加載模塊。
AMD依賴前置,js能夠方便知道依賴模塊是誰,當即加載;而CMD就近依賴,須要使用把模塊變爲字符串解析一遍才知道依賴了那些模塊,這也是不少人詬病CMD的一點,犧牲性能來帶來開發的便利性,實際上解析模塊用的時間短到能夠忽略。

以上就是三者的異同,若有疑問或建議,請參考如下文章或聯繫我,謝謝。
</br></br>

做者:乘着風連接:https://www.jianshu.com/p/09ffac7a3b2c來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索