摘自 居玉皓 的 Webpack實戰:入門、進階與調優
CommonJS, ES6 Module, AMD, UMD 做簡單的比較
CommonJS
模組 - 每個模組是擁有各自的作用域
CommonJS在每個模組都開頭添加了以下程式碼:
var module = { |
導出 - 利用.export關鍵字
module.exports = { |
導入 - 利用require關鍵字
// calculator.js |
- require有兩種情況:
- module是第一次被載入。首先執行該模組,然後導出內容。
- module曾被加載入過。模組內的程式碼不會再次執行,而是直接導出上次執行後得到的結果。
ES6 Module
導出
// 命名導出 - 自訂關鍵字 or 使用as |
導入
// calculator.js |
這裡的React必須寫在大括號前面,而不能順序顛倒,否則會提示語法錯誤。
CommonJS與ES6 Module的區別
動態與靜態
CommonJS
- require的模組可以動態指定,可以通過if語句判斷是否加載某個模組
- 被執行前,並沒有辦法確定明確的依賴關係,模組的導入、導出發生在代碼的運行階段。
ES6 Module
- 導入、導出語句都是聲明式的,它不支持導入的路徑是一個表達式,並且導入、導出語句必須位於模組的頂層作用域。因此我們說,ES6 Module是一種靜態的模組結構,在ES6代碼的編譯階段就可以分析出模組的依賴關係。好處是:
- 死代碼檢測和排除。靜態分析工具檢測出哪些模組沒有被調用過。未被調模組永不執行->死代碼。打包時去掉死代碼,以減小打包資源體積。
- 模組變量類型檢查。JavaScript屬於動態類型語言,不會在代碼執行前檢查類型錯誤(比如對一個字符串類型的值進行函數調用)。ES6 Module的靜態模組結構有助於確保模組之間傳遞的值或接口類型是正確的。
- 編譯器優化。在CommonJS等動態模組系統中,無論採用哪種方式,本質上導入的都是一個對象,而ES6 Module支持直接導入變數,減少了引用層級,程序效率更高。
- 導入、導出語句都是聲明式的,它不支持導入的路徑是一個表達式,並且導入、導出語句必須位於模組的頂層作用域。因此我們說,ES6 Module是一種靜態的模組結構,在ES6代碼的編譯階段就可以分析出模組的依賴關係。好處是:
CommonJS是值拷貝/ ES6 Module是reference
非Module文件加載 - 如下:
import './jquery.min.js'; |
AMD
- Asynchronous Module Definition(異步模組定義)
它加載模組的方式是異步的。
// 導出 |
非阻塞性, 會繼續執行require後面的code, 但是語法冗長, 或許有callback hell.
UMD
Universal Module Definition,也就是通用模組標準
早在ES6還沒發布前, 算是一種集合體. 支持AMD, CommonJS
// calculator.js |