首頁 > 軟體

前端工程化cjs umd esm 打包差異詳解

2022-09-26 14:05:26

模組

先簡單說一下模組這玩意:

一個模組(module)就是一個檔案。一個指令碼就是一個模組。就這麼簡單。

內部有自己的區域性作用域以及程式,外部可以通過模組暴露的介面進行呼叫、執行模組內的程式

為什麼要模組

我們從另一個角度出發,如果沒有模組,會怎麼樣?

  • 汙染全域性作用域
  • script 標籤自己插入自己手動排好順序
  • ....

總之就是,難以複用、難以維護!

所以很明顯,我們需要模組化。

但是不同的環境是有不同的模組話機制的~

就目前來說,常用常見的模組化打包方式有這麼三種:

  • common js
  • ES module
  • UMD

commonjs

cjs 是 Node 中的模組規範,匯入和匯出的 API 為

  • require
  • exports

它的 require 是同步的,因為 node 模組系統是需要同步讀取模組檔案內容並編譯執行以得到模組介面的。

而在瀏覽器端,一般都以 script 標籤引入 —— script 標籤可是天生非同步的。

so 它本身只可以執行在 node 環境下,比如ms

他就是隻支援 cjs,如果你想用 CDN 直接在瀏覽器中使用是不行的

但是,webpack 是支援 cjs 的,通過 webpack 就可以將其執行在瀏覽器中。所以,通過 webpack 打包你就可以在瀏覽器環境中使用 ms。

也就是說,在 webpack 環境下,cjs 即支援 node 環境,也支援瀏覽器環境~

除此之外,他是在執行時載入的,模組輸出的也只是拷貝

UMD

全稱 Universal Module Definition —— “通用模組定義”

這也算是應運而生,它可以在執行或者編譯時讓同一個程式碼模組使用 cjs 或者 amd

amd : Asynchronous ModuleDefinition
非同步模組定義,採用非同步方式載入模組。所有依賴模組的語句,都定義在一個回撥函數中,等到模組載入完成之後,這個回撥函數才會執行

也就是 集它們於一身,所以它既可以在 node 或者 webpack 環境下用 require 參照使用,也可以 在瀏覽器中 直接用 script 參照 CDN 使用

實現大概如下:

((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, ($) => {
    //todo
});

也就是在定義模組的時候檢測當前環境和模組定義的方式,將各種模組方法轉換為同一種寫法

有一些包就是用的這種打包方法

有些包是多種打包方法都有,比如

antd

es/index.js下就是 es6 的打包方式(下面會說)

dist/antd.js下就是 umd 的打包方式

lib/index.js下就是 cjs 的打包方式

es moudle

上面說的可能都是過去一段時間裡最好的打包方式,但是 在未來 ES6 的打包方式 應該還是會全面替代它們

esm 是基於 ESMAScript 模組化規範的 —— 他的爹就代表著 他的前途一片光明

node 環境和瀏覽器環境下都支援~

另外他模組輸出的是值的參照。

還是在編譯時載入,這意味著可以在編譯期間進行 Tree Shaking,減少 js 體積

另外還支援動態引入

const a = await import ('xxx')

總結

不同之處在於:

  • 何時載入?執行時還是編譯?
  • 引出的值是拷貝還是參照?
  • 可在哪些環境下使用?
  • 同步還是非同步?

以上就是前端工程化cjs umd esm 打包差異詳解的詳細內容,更多關於前端cjs umd esm 打包差異的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com