JavaScript 模組化
定義
模組化是什麼呢,我們先來看看百度是怎麼定義的:
雖然百度的解釋有時候太過於官方,但還是十分準確的。
模組化的意義
a. 實現js檔案的非同步載入,避免網頁失去響應。
b. 管理模組之間的依耐性,便於程式碼的編寫和維護。
c. 封閉作用域 ,不會汙染全域性變數,以及不用擔心命名衝突。
js中的模組化分為三種:commonJS,MDN,AMD。
1.commonJS
Node.js是commonJS規範的主要實踐者,它有四個重要的環境變數為模組化的實現提供支援:module、exports、require、global。實際使用時,用module.exports定義當前模組對外輸出的介面(不推薦直接用exports),用require載入模組。 commonJS規範是應用於後端的一個模組化規範,而AMD和CMD是應用前端的模組化規範。
let jquery = require("jquery"); //引入模組 引入自定義的模組時 寫路徑 可省略.js
module.exports = { //把自身變成一個模組 即定義模組
print = function(){ //對外暴露的部分
......
}
}
2.AMD
AMD(非同步模組定義,Asynchronous Module Definition),依賴前置。由於不是JavaScript原生支援,使用AMD規範進行頁面開發需要用到對應的庫函式,也就是大名鼎鼎
RequireJS
,實際上AMD 是 RequireJS 在推廣過程中對模組定義的規範化的產出。
define(["xx","xx"],function(){ //把js檔案模組化 []中是載入當前js需要依賴的js檔案路徑 有配置檔案的話可以直接寫 名字
return {
print : function(){ //對外暴露的部分
....
}
}
})
require([],function(){ // 引入定義好的js檔案 [] 有配置檔案的話 直接載入配置檔案
})
3.CMD
CMD 即
Common Module Definition
通用模組定義,CMD規範是國內發展出來的,就像AMD有個requireJS,CMD有個瀏覽器的實現SeaJS,SeaJS要解決的問題和requireJS一樣,只不過在模組定義方式和模組載入(可以說執行、解析)時機上有所不同 。特點是依賴就近。
// 定義模組
define(function(require, exports, module) {
var $ = require('jquery.js')
$('div').addClass('active');
});
// 載入模組
seajs.use(['myModule.js'], function(my){
});
AMD和CMD的區別
關於這兩個的區別網上可以搜出一堆文章,簡單總結一下
最明顯的區別就是在模組定義時對依賴的處理不同
- AMD推崇依賴前置,在定義模組的時候就要宣告其依賴的模組
- CMD推崇就近依賴,只有在用到某個模組的時候再去require
這種區別各有優劣,只是語法上的差距,而且requireJS和SeaJS都支援對方的寫法
AMD和CMD最大的區別是對依賴模組的執行時機處理不同,注意不是載入的時機或者方式不同
很多人說requireJS是非同步載入模組,SeaJS是同步載入模組,這麼理解實際上是不準確的,其實載入模組都是非同步的,只不過AMD依賴前置,js可以方便知道依賴模組是誰,立即載入,而CMD就近依賴,需要使用把模組變為字串解析一遍才知道依賴了那些模組,這也是很多人詬病CMD的一點,犧牲效能來帶來開發的便利性,實際上解析模組用的時間短到可以忽略
為什麼我們說兩個的區別是依賴模組執行時機不同,為什麼很多人認為ADM是非同步的,CMD是同步的(除了名字的原因。。。)
同樣都是非同步載入模組,AMD在載入模組完成後就會執行改模組,所有模組都載入執行完後會進入require的回撥函式,執行主邏輯,這樣的效果就是依賴模組的執行順序和書寫順序不一定一致,看網路速度,哪個先下載下來,哪個先執行,但是主邏輯一定在所有依賴載入完成後才執行
CMD載入完某個依賴模組後並不執行,只是下載而已,在所有依賴模組載入完成後進入主邏輯,遇到require語句的時候才執行對應的模組,這樣模組的執行順序和書寫順序是完全一致的
這也是很多人說AMD使用者體驗好,因為沒有延遲,依賴模組提前執行了,CMD效能好,因為只有使用者需要的時候才執行的原因