我所了解的三種模組加載方式分別是CommonJS、AMD和CMD
網上關於這三種模組加載方式講解的文章很多,我就簡單的做個介紹,如果想深入了解一下可以去網上查閱一下相關的資料。
(1)CommonJS
在CommonJS中,一個單獨的檔案就是一個模組。被呼叫模組內使用exports暴露接口,呼叫模組使用require呼叫暴露出來的接口。
範例如下:
// student.js // 私有变量 var a = 123; function add(student) { console.log('Add student:' + student); } // exports对象上的方法和变量是外部可访问的 exports.add = add;
1 // 使用require載入student.js模組2 var student = require('./student.js');
CommonJS載入模組是「同步」的,也就是說,如果我們要呼叫被呼叫模組中的公共方法和變量,一定要等到被呼叫模組載入完畢後才可以。用於服務端的NodeJS就採用的CommonJS來管理模組。但在瀏覽器端,同步載入會因為收到網路環境的影響存在很大的不確定性,所以CommonJS不適合瀏覽器端。
如果在瀏覽器環境下想要從伺服器載入模組,就必須使用「非同步」的方式。所以就出現了AMD和CMD解決方案。
(2)AMD(Asynchromous Module Definition)
requireJS就是一種使用AMD非同步載入模組的管理外掛程式。 AMD模組支援對象,函數,建構器,字串,JSON等各種類型的模組。
AMD規範使用define方法定義模組:
//define(param1,param2) 通过define方法定义模块 //@param1: 数组,元素为引入的依赖模块 //@param2: 回调函数,通过形参传入依赖 define(['firstModule','secondModule'],function(firstModule,secondModule){ function foo(){ firstModule.test(); } // 暴露foo() return {foo:foo}; });
同時,AMD允許使用define方法定義模組是相容於CommonJS規範,可以使用require和exports。
define(function(require,exports,module){ var reqModule = require("./firstModule"); reqModule.test(); exports.pubPort = function(){ // 函数体 } });
(3)CMD
CMD和AMD的區別主要體現在對依賴模組的執行時機上,AMD是「依賴前置」。主張提前載入所需模組,CMD是「依賴就近」。也就是可以用到的時候再加載。有點類似Java中的「餓漢模式」和「懶漢模式」。
從requireJS 2.0開始,也可以延遲載入了。
舉個栗子:
// AMD——依赖前置 define(['./a','./b'],function(a,b){ //提前声明要依赖的模块 }); // CMD define(function(require,exports,module){ //依赖可以就近写 var a = require('./a'); a.test(); //软依赖 if(status){ var b = require('./b'); b.test(); }
這裡有個名詞叫軟依賴,我個人理解軟依賴就是不一定依賴,硬依賴就是一定會依賴的模組,軟依賴就是需要才依賴,不需要就不依賴,根據status判斷。
(4)UMD
UMD——Universal Module Definition,通用的模組定義
UMD等於CommonJS加上AMD。 UMD的工作其實就是做了一個判斷:
- 先判斷目前環境對NodeJs支援的模組是否存在,存在就用Node.js模組模式(exports)。
- 如果不支持,就判斷是否支持AMD(define),存在就使用AMD方式加載。
覺得自己對UMD還不是很理解,不知道具體該怎麼去用。還是繼續去了解了解。加油!