from:https://www.jianshu.com/p/09ffac7a3b2cnode
隨着JS模塊化編程的發展,處理模塊之間的依賴關係成爲了維護的關鍵。npm
AMD,CMD,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,即 (Asynchronous Module Definition),這種規範是異步的加載模塊,requireJs應用了這一規範。先定義全部依賴,而後在加載完成後的回調函數中執行:
require([module], callback);
用AMD寫上一個模塊:
require(['clock'],function(clock){ clock.start(); });
AMD雖然實現了異步加載,可是開始就把全部依賴寫出來是不符合書寫的邏輯順序的,能不能像commonJS那樣用的時候再require,並且還支持異步加載後再執行呢?
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來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。