AMD、CMD、CommonJS、UMD、ESM( JS模塊化規范)


隨着前端發展的不斷進步,JavaScript的模塊化不僅在NodeJS中應用,也被拿到了瀏覽器上得到應用,所以出現了一些模塊化的規范

AMD(Asynchromous Module Definition - 異步模塊定義)

AMD是RequireJS在推廣過程中對模塊定義的規范化產出,AMD是異步加載模塊,推崇依賴前置。

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

  

代碼中依賴被前置,當定義模塊(module1)時,就會加載依賴(jquery)

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(cjs)

提到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...  這里是真正的函數體
});

  

 ESM(ECMA Script Modules)

ESM是ES6中的模塊化規范,在nodeJS新版本中可以直接使用,現在大部分瀏覽器也開始支持(在script標簽上設置type="module"),

ES6 在語言標准的層面上,實現了模塊功能,而且實現得相當簡單,完全可以取代現有的 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案。

// 寫法一 
export var m = 1;
// 寫法二 
var m = 1; export { m };
// 寫法三 
var n = 1; export { n as m };
// 寫法四 
var n = 1; export default n;
// 寫法五 
if (true) { import('./myModule.js').then(({ export1, export2 }) => { /* ... */ }); }
// 寫法六 
Promise.all([import('./module1.js'),
import('./module2.js'),
import('./module3.js')]).then(([module1, module2, module3]) => { /* ... */ });

 

Reference

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM