js模塊化

一. 什麼是模塊化

模塊化是一種將系統分離成獨立功能部分的方法,可將系統分割成獨立的功能部分,嚴格定義模塊接口、模塊間具備透明性。
js中的模塊化方法,大體分爲如下幾個:commonJS, amd, cmd, umd, esModule。下面咱們來逐個擊破。

二. CommonJS

commonjs規範爲js提供一個美好的願景-但願js可以在任何地方都去運行。它的定義也十分簡單,主要分爲:模塊引用、模塊定義、模塊標識。
1. 模塊引用

在commonjs中,使用require方法引用模塊javascript

2. 模塊定義
在模塊中,上下文提供了exports對象,用來導出模塊的方法或變量。另外還存在一個module對象,它表明着模塊自己。在node.js中,一個文件就是一個模塊。具體導出方式:
module.exports.test = () => {
  return "test";
}
3. 模塊標識

模塊標識實際上就是require方法的參數,即引入模塊的路徑。java

commonjs的優勢:
  • 全部代碼都運行在模塊做用域,不會污染全局
  • 模塊的加載只須要運行一次,之後都從緩存中加載
  • 模塊加載是同步的,按照代碼中出現的順序
  • 簡單易用
commonjs缺點:
  • 同步加載的方法,不適合瀏覽器環境。瀏覽器環境瓶頸在於帶寬,服務器環境瓶頸在於cpu和內存。瀏覽器環境須要異步加載模塊。
  • 非es官方標準
實現:node.js

三. AMD

amd規範是commonjs的延伸,amd全名:異步模塊定義,針對瀏覽器設計。定義一套模塊異步加載規範,來解決commonjs同步加載問題。
它的規範只有1個定義:
define(id: string, dependencies: Array<string>, factory: Function)

舉個🌰

定義:
define("module", ["module1", "module2"], function(m1, m2) {
  return "test";
})
使用:
require(["module", "../file"], function(module, file) { /* ... */ });
與commonjs區別:
  1. amd使用define定義模塊,而在node實現中是隱式包裝。
  2. 內容須要經過返回(return)的方式實現導出。
AMD優勢:
  • 解決了瀏覽器異步加載模塊問題
AMD缺點:
  • 是commonjs模塊化規範的一種妥協方式
  • 非es官方標準
實現:require.js

四. CMD

cmd規範由玉伯提出,與amd主要區別在於:定義模塊和依賴模塊引入的部分。
  1. amd須要聲明模塊的時候,指定全部依賴。
  2. cmd更接近node.js對commonjs規範的定義:define(factory),依賴部分, cmd能夠動態引入:
define(function(require, exports, module) {
})
CMD優勢:
  • 更容易在node.js中運行
  • 延遲執行
CMD缺點:
  • 依賴 SPM 打包,模塊的加載邏輯偏重
  • 非es官方標準

五. UMD

爲了讓同一個模塊,可以在瀏覽器環境和服務器環境可以兼容。umd是commonjs和amd的結合體。其代碼以下:
(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define([], factory);
    } else if (typeof exports === 'object') {
        // commonjs,如 nodejs
        module.exports = factory();
    } else {
        // root == window or global
        root.returnExports = factory();
  }
}(this, function () {
    return {};
}));
UMD優勢:
  • 統一瀏覽器端和服務器端規範
  • 非es官方標準

六. ES Module

es module 是es官方提供的js模塊化標準方案,相對社區上的amd, cmd,umd等,它是標準。其設計思想,儘可能靜態化,這樣編譯時,才能肯定依賴關係。這也是webpack 搖樹可以實現的關鍵緣由。
es module使用 import 導入模塊。 使用 export 導出模塊。
舉個🌰
// a.js
let foo = "hello";
export foo;
// b.js
import { foo } from "a";
console.log(foo); // hello
commonjs與es module區別:
commonjs es module
導出值 拷貝導出值,模塊內部值變化不影響引用值 import是值的引用
運行機制 運行時加載依賴,加載的是一個對象 編譯時加載,加載的是模塊的接口定義,在代碼靜態解析時會生成
相關文章
相關標籤/搜索