前幾天我透過 esbuild 解決了兩個小專案(side project)的 Bundling 問題,執行起來不但速度快,其上手的難度也比 webpack 還低,這篇文章將會介紹 esbuild
的基本使用方式。
安裝 esbuild 套件
npm install --save-exact --save-dev esbuild
查看版本
npx esbuild --version
替 Browser 應用程式打包
我之前替 Tampermoneky 寫了一個 ChatGPT 的 Userscript,可以替 ChatGPT 加上語音能力(語音合成與語音識別),但是我有動態載入 rxjs
這個 npm 套件,可惜近期 ChatGPT 加入了 CSP (Content Security Policy) 的限制,導致我無法從 cdn.jsdelivr.net
動態載入 rxjs
,因此我必須將整份 rxjs
打包進去 Userscript 中才行!
還好這個過程並不複雜,我五分鐘就搞定了,步驟如下:
-
我主要的程式碼原本這樣寫
const {
Observable,
catchError,
defer,
filter,
fromEvent,
interval,
map,
of,
retry,
shareReplay,
Subject,
switchMap,
take,
tap,
timer
} = await import('https://cdn.jsdelivr.net/npm/@esm-bundle/rxjs/esm/es2015/rxjs.min.js');
-
我改用 esbuild 打包的過程如下
初始化 package.json
npm init -y
安裝 rxjs 套件
npm install rxjs
改寫我原本 JS 程式碼的 import
方式:
import {
Observable,
catchError,
defer,
filter,
fromEvent,
interval,
map,
of,
retry,
shareReplay,
Subject,
switchMap,
take,
tap,
timer
} from 'rxjs';
執行 esbuild 打包程式碼
npx esbuild app.js --bundle --outfile=out.js --platform=browser
就這麼簡單!
你還可以透過 --minify
參數對輸出 JS 進行最小化,加上 --sourcemap
則會自動產生 Source map 檔案,例如:
npx esbuild app.js --bundle --minify --sourcemap --outfile=out.js
注意: --platform
的預設值就是 browser
,預設可以忽略不寫。
如果你想要針對特定瀏覽器版本進行打包,esbuild 還能自動幫你打包出符合特定瀏覽器版本的程式碼,例如:
npx esbuild app.js --bundle --minify --sourcemap --outfile=out.js --target=chrome58,firefox57,safari11,edge16
替 Node 應用程式打包
如果要替 Node 應用程式打包,只需要將 --platform
參數改成 node
即可,例如:
npx esbuild app.js --bundle --platform=node --target=node
如果要針對特定 Node 版本進行打包,也是沒問題的,例如:
npx esbuild app.js --bundle --platform=node --target=node10.4
另外,你也可以指定輸出的格式,例如:
npx esbuild app.js --bundle --platform=node --target=node --format=esm
--format
可設定的值有 iife
, cjs
, 與 esm
!
如果你不想將 Node 的外部依賴項目跟 esbuild 打包在一起,esbuild 在打包時不支援許多特定於 Node.js 的功能,例如 __dirname、import.meta.url、fs.readFileSync 和 *.node 原生二進制模組。您可以通過將 --packages
設定為 external
來排除所有相依檔案:
npx esbuild app.jsx --bundle --platform=node --packages=external
相關連結