bundlejs:前端不容錯過的 esbuild 在線打包器

2024年2月6日 18点热度 0人点赞

傢好,很高興又見面了,我是"高級前端‬進階‬",由我帶著大傢一起關註前端前沿、深入前端底層技術,大傢一起進步,也歡迎大傢關註、點贊、收藏、轉發!

高級前端‬進階

今天給大傢帶來的主題是 bundlejs,一個基於 esbuild 優秀在線打包器和包大小檢查器,希望大傢真正用的上,話不多說,直接進入正題。

1.什麼是 bundlejs

bundlejs(發音為 bundle js)是一種快速簡便的方法來對 typescript、javascript、jsx 和 npm 項目進行 tree shaking、打包、minify 和 compress(在 gzip 或 brotli 中),同時可以查看總包的文件大小。bundlejs 是一個類似於 bundlephobia 的在線工具,不同的是 bundlejs 是在終端瀏覽器本地完成打包。

bundlejs 的 logo

bundlejs 旨在通過遵循打包器使用的相同方法來生成更準確的包大小估計:

  • 在本地進行所有打包
  • 輸出 tree shaking 打包代碼,無需安裝任何 npm 包和 typescript 支持。
  • 獲取生成的包大小

使用 bundlejs 的好處是:

  • 更容易調試錯誤
  • 可以驗證生成的打包代碼
  • 配置打包能力,支持 tree shaking 打包代碼,同時進行最終 bundle 的可視化分析
  • 可以支持離線打包,隻要之前使用過該模塊
  • 支持來自不同內容交付網絡 (CDN) 的不同類型的模塊,例如:CDN 范圍從 deno 模塊到 npm 模塊,再到隨機的 github 腳本等等

目前 bundlejs 在 Github 上通過 MIT 協議開源,有超過 600 的 star,是一個值得長期關註的前端開源項目。

2.bundlejs 支持打包 Treeshaking 和代碼壓縮

bundlejs 內部依賴 esbuild 來實現打包、轉換、轉譯、壓縮、tree shaking 和遍歷文件的能力。 更加具體的來說,bundlejs 使用 esbuild-wasm,它能夠訪問這些功能的一個子集,關鍵限制主要包括:

  • npm 隻在 Node.js 運行,所以 bundlejs 沒有 package.json 或 npm install( StackBlitz WebContainers 除外)
  • 瀏覽器不像 nodejs 那樣工作,沒有訪問文件系統的簡單方法和能力,因此存儲和訪問文件是不切實際的, esbuild 在 Node.js 上運行的方式並不適合 Web 端
  • 由於 esbuild-wasm 在瀏覽器上運行時的諸多限制(沒有 npm 和 nodejs),唯一的選擇是模塊來自 Web,但 esbuild 本身不支持導入 http(s)://.. . 模塊,因此需要不同的解決方案

為了解決這些問題,esbuild 的插件系統發揮了作用。 bundlejs 總共依賴 4 個插件來解決這些限制:

  • HTTP 插件:獲取和緩存模塊
  • CDN 插件:將 npm 包導入(稱為裸導入)重定向到內容交付網絡 (CDN) url 以獲取
  • EXTERNALS 插件 :將某些 import/export 模塊標記為要從打包中排除的模塊
  • ALIAS 插件 : 將某些導入/導出別名到不同名稱的模塊

以上插件實現了 esbuild-wasm 創建 javascript 包,而 esbuild-wasm 是一個用於 esbuild 的跨平臺 WebAssembly 二進制文件,一個 JavaScript 打包器和壓縮器。

3.使用 bundlejs

基礎配置

在 v0.2 中,bundlejs 添加了對自定義配置 (configs) 的支持,目前支持大部分 esbuild 的構建選項,以及一些用於更改默認 CDN 和壓縮算法的添加選項。

{
  "cdn": "https://unpkg.com",
  "compression": "gzip",
  // 註意:有 3 種可用的壓縮算法,brotli、gzip 和 lz4
  "esbuild": {
      "target": [ "esnext"],
      "format": "esm",
      "bundle": true,
      "minify": true,
      "treeShaking": true,
      "platform": "browser"
  }
}

同時,可以借助於 bundlejs 打包平臺提供的能力在不同開發者之間分享配置。

CDN

內容交付網絡 (CDN) 是一種在全球范圍內快速分發代碼的方法。 在 bundlejs 的上下文中,CDN 代表 bundlejs 可以從中獲取的代碼在線存儲庫。

例如,unpkg.com 是一個快速的全球內容交付網絡,適用於 npm 上的所有內容。 它用於使用如下 URL 快速輕松地從 npm 上的任何包加載任何文件:
https://unpkg.com/package-name@version/file.js,其他平臺,如: skypack.dev,esm.sh 也提供了類似功能。

默認情況下,bundlejs 允許使用如下的代碼:

export * from "@okikio/animate";

bundlejs 會自動從 unpkg 中獲取特定的包。

{
    "cdn": "https://cdn.esm.sh",
    // OR
    "cdn": "skypack"
}

壓縮算法

bundlejs 提供了使用以下方式進行打包的選項:

  • brotli :產生最小的包大小但它是最慢的
  • gzip : 產生第二小的包大小,但它比 brotli 快(默認)。最終選擇將 pako 替換為 denoflate 作為 gzip 的默認壓縮算法,它比 pako 更快更小。
  • lz4 : 產生最大的包大小但它是最快的包算法。bundlejs 使用 deno-lz4,其也通過 WASM 運行,但 deno-lz4 壓縮自身的方式與 deno-brotli 略有不同

就 brotli 來說,其是一種壓縮算法,可以很好地壓縮數據,但是,與其他替代方案相比,它的速度非常慢。 bundlejs 通過 deno-brotli 包含了一個 WASM 版本的 brotli,deno-brotli 主要做了以下兩件事情:

  • 將 deno-brotli 所需的巨大 WASM 文件壓縮成 lz4 壓縮字符串,然後可以通過 lz4 解壓縮,從而可以輕松地將 WASM 存儲為 js 文件(結果是構建工具支持很好,因為 WASM 隻是一個字符串 在 JS 文件中,加上它很好地解決了生態系統問題)。
  • 通過將 WASM 作為 js 文件,實際上可以將 WASM 作為 js 模塊預加載

關於 bundlejs 的更多用法,比如:壓縮質量、Aliases 和 Externals、Esbuild 配置選項、編輯器按鈕、JSX支持、共享打包會話、Bundle 分析、安全和性能等高級用法本文不再展開,大傢可以參考文末的資料自行學習

4.本文總結

本文主要和大傢介紹 bundlejs,即一個基於 esbuild 的優秀在線打包器和包大小檢查器 。相信通過本文的閱讀,大傢對 bundlejs 會有一個初步的了解。

因為篇幅有限,文章並沒有過多展開,如果有興趣,可以在我的主頁繼續閱讀,同時文末的參考資料提供了大量優秀文檔以供學習。最後,歡迎大傢點贊、評論、轉發、收藏!

參考資料

https://blog.okikio.dev/documenting-an-online-bundler-bundlejs

https://bundlejs.com/

https://github.com/okikio/bundlejs