1. 程式人生 > >認識AMD、CMD、UMD、CommonJS

認識AMD、CMD、UMD、CommonJS

0、導言

JavaScript的生態系統一直在穩步增長,當各種元件混合使用時,就可能會發現不是所有的元件都能“和平共處”,為了解決這些問題,各種模組規範就出來了。

1、AMD(Asynchromous Module Definition - 非同步模組定義)

AMD是RequireJS在推廣過程中對模組定義的規範化產出,AMD是非同步載入模組,推崇依賴前置。

define('module1', ['jquery'], ($) => {
  //do something...
});

程式碼中依賴被前置,當定義模組(module1)時,就會載入依賴(jquery)

2、CMD(Common Module Definition - 公共模組定義)

CMD是SeaJS在推廣過程中對模組定義的規範化產出,對於模組的依賴,CMD是延遲執行,推崇依賴就近。

define((require, exports, module) => {
  module.exports = {
    fun1: () => {
       var $ = require('jquery');
       return $('#test');
    } 
  };
});

如上程式碼,只有當真正執行到fun1方法時,才回去執行jquery。

同時CMD也是延自CommonJS Modules/2.0規範

CommonJS

提到CMD,就不得不提起CommonJS,CommonJS是服務端模組的規範,由於Node.js被廣泛認知。

根據CommonJS規範,一個單獨的檔案就是一個模組。載入模組使用require方法,該方法讀取一個檔案並執行,最後返回檔案內部的module.exports物件。

//file1.js
moudle.exports = {
  a: 1
};

//file2.js
var f1 = require('./file1');
var v = f1.a + 2;
module.exports ={
  v: v
};

CommonJS 載入模組是同步的,所以只有載入完成才能執行後面的操作。像Node.js主要用於伺服器的程式設計,載入的模組檔案一般都已經存在本地硬碟,所以載入起來比較快,不用考慮非同步載入的方式,所以CommonJS規範比較適用。但如果是瀏覽器環境,要從伺服器載入模組,這是就必須採用非同步模式。所以就有了 AMD CMD 解決方案。

UMD(Universal Module Definition - 通用模組定義)

UMD又是個什麼玩意呢?UMD是AMD和CommonJS的一個糅合。AMD是瀏覽器優先,非同步載入;CommonJS是伺服器優先,同步載入。

既然要通用,怎麼辦呢?那就先判斷是否支援node.js的模組,存在就使用node.js;再判斷是否支援AMD(define是否存在),存在則使用AMD的方式載入。這就是所謂的UMD。

((root, factory) => {
  if (typeof define === 'function' && define.amd) {
    //AMD
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    //CommonJS
    var $ = requie('jquery');
    module.exports = factory($);
  } else {
    //都不是,瀏覽器全域性定義
    root.testModule = factory(root.jQuery);
  }
})(this, ($) => {
  //do something...  這裡是真正的函式體
});