前幾天我透過 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
相關連結