詳解AMD、CommonJS和UMD模塊化規範

開發的時候,我們經常會把某些功能封裝成可複用的模塊。模塊封裝了功能,並且對外暴露一個API。隨着Node.js的誕生和發展,JavaScript可以在服務端運行,同時客戶端應用也越來越流行,JavaScript界產生了對優秀和健壯模塊系統的需求。在JavaScript中定義模塊的規範也隨之產生。

這裏,將詳細介紹最常見的兩個定義模塊的方法AMD和CommonJS,以及它們的結合UMD.

一、CommonJS

CommonJS模塊可以說是當前最流行的模塊定義規範。相比於AMD,它的工作效率更高、語法更簡單。一開始,CommonJS模塊是JavaScript服務器模塊的規範。

基本原理

實現編譯代碼,創建一個比原先更大的代碼包,其中包含了所有應用運行所需的代碼。

語法

const $ = require('jquery');       //將依賴加載到當前文件

exports.init = function(){
    ...
};

特點

  • 沒有回調函數
  • 同步加載,每個require語句會短暫阻塞代碼的運行,知道模塊加載完畢。不過這個加載不是通過網絡加載,而是從內存或者文件系統中加載,所以這個過程很快。
  • 代碼簡單易懂
  • CommonJS模塊不適合瀏覽器,因爲瀏覽器的加載機制不支持同步。需要用打包工具把所有CommonJS模塊打包成一個js文件。

二、AMD——爲瀏覽器設計的模塊定義規範

AMD:Asynchronous Module Definition(異步模塊規範),最老的方式之一,專爲瀏覽器而設計。

基本原理

用異步加載技術來定義模塊和依賴。提供define方法和require方法來定義和加載模塊。

語法

define方法:

define(
    '模塊id',
    ['依賴數組'],
    function([依賴數組]){     //工廠函數
        ...
    }
);

工廠函數內部包含了模塊代碼,工廠函數最後返回的結果,就是要暴露給其他模塊的功能。

特點

  • 用AMD定義的模塊至少需要一個工廠函數來暴露API給其他模塊使用。
  • 依賴數組中的依賴會被異步加載。
  • 模塊的加載通過客戶端(瀏覽器)向服務器發送HTTP請求來完成的,這個傳輸過程需要大量時間。
  • 可以定義具名模塊,也可以定義匿名模塊。具名模塊通過開發者定義的名字加載,匿名模塊隱式的以文件名加載。

require方法:

require(['jquery'],
    function($){        //回調函數
    ...
    }
);

require方法與define方法相對應,用來顯示的加載模塊。

特點

  • 可以在代碼的任何地方使用require加載另一個模塊。
  • require調用會發送一個請求來下載模塊。
  • 異步加載,只有在回調函數裏才能獲取新拿到的API。

AMD模塊加載流程示意圖
這裏寫圖片描述

UMD——通用模塊規範

UMD:Universal Module Definition(通用模塊規範)是由社區想出來的一種整合了CommonJS和AMD兩個模塊定義規範的方法。

基本原理

用一個工廠函數來統一不同的模塊定義規範。

原則

  • 所有定義模塊的方法需要單獨傳入依賴
  • 所有定義模塊的方法都需要返回一個對象,供其他模塊使用

例如,利用UMD定義一個toggler模塊:

(function (global, factory) {
    if (typeof exports === 'object' && typeof module !== undefined) { //檢查CommonJS是否可用
        module.exports = factory(require('jquery'));
    } else if (typeof define === 'function' && define.amd) {      //檢查AMD是否可用
        define('toggler', ['jquery', factory])
    } else {       //兩種都不能用,把模塊添加到JavaScript的全局命名空間中。
        global.toggler = factory(global, factory);
    }
})(this, function ($) {
    function init() {

    }
    return {
        init: init
    }
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章