Bun 的打包器 API 深受 esbuild 啟發。從 esbuild 遷移到 Bun 的打包器應該相對無痛。本指南將簡要解釋為什麼您可能考慮遷移到 Bun 的打包器,並為那些已經熟悉 esbuild API 的人提供並排 API 比較參考。
有一些行為差異需要注意。
NOTE
**默認打包。** 與 esbuild 不同,Bun 始終默認打包。這就是為什麼在 Bun 示例中不需要 `--bundle` 標志。要逐個轉譯每個文件,請使用 `Bun.Transpiler`。NOTE
**它只是打包器。** 與 esbuild 不同,Bun 的打包器不包含內置的開發服務器或文件監聽器。它只是打包器。打包器旨在與 `Bun.serve` 和其他運行時 API 結合使用以實現相同效果。因此,所有與 HTTP/文件監聽相關的選項都不適用。性能
憑借注重性能的 API 和經過廣泛優化的基於 Zig 的 JS/TS 解析器,Bun 的打包器在 esbuild 的 three.js 基准測試中比 esbuild 快 1.75 倍。
CLI API
Bun 和 esbuild 都提供命令行界面。
bash
# esbuild
esbuild <entrypoint> --outdir=out --bundle
# bun
bun build <entrypoint> --outdir=out在 Bun 的 CLI 中,簡單的布爾標志(如 --minify)不接受參數。其他標志(如 --outdir <path>)接受參數;這些標志可以寫為 --outdir out 或 --outdir=out。一些標志(如 --define)可以指定多次:--define foo=bar --define bar=baz。
| esbuild | bun build | 注釋 |
|---|---|---|
--bundle | n/a | Bun 始終打包,使用 --no-bundle 禁用此行為。 |
--define:K=V | --define K=V | 小的語法差異;無冒號。esbuild --define:foo=barbun build --define foo=bar |
--external:<pkg> | --external <pkg> | 小的語法差異;無冒號。esbuild --external:reactbun build --external react |
--format | --format | Bun 目前支持 "esm" 和 "cjs",但計劃支持更多模塊格式。esbuild 默認為 "iife"。 |
--loader:.ext=loader | --loader .ext:loader | Bun 支持與 esbuild 不同的一組內置加載器;完整參考請參閱打包器 > 加載器。esbuild 加載器 dataurl、binary、base64、copy 和 empty 尚未實現。--loader 的語法略有不同。esbuild app.ts --bundle --loader:.svg=textbun build app.ts --loader .svg:text |
--minify | --minify | 無差異 |
--outdir | --outdir | 無差異 |
--outfile | --outfile | 無差異 |
--packages | --packages | 無差異 |
--platform | --target | 為與 tsconfig 保持一致而重命名為 --target。不支持 neutral。 |
--serve | n/a | 不適用 |
--sourcemap | --sourcemap | 無差異 |
--splitting | --splitting | 無差異 |
--target | n/a | 不支持。Bun 的打包器此時不執行語法降級。 |
--watch | --watch | 無差異 |
--allow-overwrite | n/a | 不允許覆蓋 |
--analyze | n/a | 不支持 |
--asset-names | --asset-naming | 為與 JS API 中的 naming 保持一致而重命名 |
--banner | --banner | 僅適用於 js 打包 |
--footer | --footer | 僅適用於 js 打包 |
--certfile | n/a | 不適用 |
--charset=utf8 | n/a | 不支持 |
--chunk-names | --chunk-naming | 為與 JS API 中的 naming 保持一致而重命名 |
--color | n/a | 始終啟用 |
--drop | --drop | |
--entry-names | --entry-naming | 為與 JS API 中的 naming 保持一致而重命名 |
--global-name | n/a | 不適用,Bun 此時不支持 iife 輸出 |
--ignore-annotations | --ignore-dce-annotations | |
--inject | n/a | 不支持 |
--jsx | --jsx-runtime <runtime> | 支持 "automatic"(使用 jsx 轉換)和 "classic"(使用 React.createElement) |
--jsx-dev | n/a | Bun 從 tsconfig.json 讀取 compilerOptions.jsx 以確定默認值。如果 compilerOptions.jsx 為 "react-jsx",或如果 NODE_ENV=production,Bun 將使用 jsx 轉換。否則,它使用 jsxDEV。打包器不支持 preserve。 |
--jsx-factory | --jsx-factory | |
--jsx-fragment | --jsx-fragment | |
--jsx-import-source | --jsx-import-source | |
--jsx-side-effects | n/a | JSX 始終假定為無副作用 |
--keep-names | n/a | 不支持 |
--keyfile | n/a | 不適用 |
--legal-comments | n/a | 不支持 |
--log-level | n/a | 不支持。這可以在 bunfig.toml 中設置為 logLevel。 |
--log-limit | n/a | 不支持 |
--log-override:X=Y | n/a | 不支持 |
--main-fields | n/a | 不支持 |
--mangle-cache | n/a | 不支持 |
--mangle-props | n/a | 不支持 |
--mangle-quoted | n/a | 不支持 |
--metafile | n/a | 不支持 |
--minify-whitespace | --minify-whitespace | |
--minify-identifiers | --minify-identifiers | |
--minify-syntax | --minify-syntax | |
--out-extension | n/a | 不支持 |
--outbase | --root | |
--preserve-symlinks | n/a | 不支持 |
--public-path | --public-path | |
--pure | n/a | 不支持 |
--reserve-props | n/a | 不支持 |
--resolve-extensions | n/a | 不支持 |
--servedir | n/a | 不適用 |
--source-root | n/a | 不支持 |
--sourcefile | n/a | 不支持。Bun 尚不支持 stdin 輸入。 |
--sourcemap | --sourcemap | 無差異 |
--sources-content | n/a | 不支持 |
--supported | n/a | 不支持 |
--tree-shaking | n/a | 始終為 true |
--tsconfig | --tsconfig-override | |
--version | n/a | 運行 bun --version 查看 Bun 版本。 |
JavaScript API
| esbuild.build() | Bun.build() | 注釋 |
|---|---|---|
absWorkingDir | n/a | 始終設置為 process.cwd() |
alias | n/a | 不支持 |
allowOverwrite | n/a | 始終為 false |
assetNames | naming.asset | 使用與 esbuild 相同的模板語法,但必須顯式包含 [ext]。ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> asset: "[name].[ext]",<br/> },<br/>});<br/> |
banner | n/a | 不支持 |
bundle | n/a | 始終為 true。使用 Bun.Transpiler 轉譯而不打包。 |
charset | n/a | 不支持 |
chunkNames | naming.chunk | 使用與 esbuild 相同的模板語法,但必須顯式包含 [ext]。ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/> |
color | n/a | Bun 在構建結果的 logs 屬性中返回日志。 |
conditions | n/a | 不支持。導出條件優先級由 target 確定。 |
define | define | |
drop | n/a | 不支持 |
entryNames | naming 或 naming.entry | Bun 支持可以是字符串或對象的 naming 鍵。使用與 esbuild 相同的模板語法,但必須顯式包含 [ext]。ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> // 當為字符串時,這等同於 entryNames<br/> naming: "[name].[ext]",<br/><br/> // 細粒度命名選項<br/> naming: {<br/> entry: "[name].[ext]",<br/> asset: "[name].[ext]",<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/> |
entryPoints | entrypoints | 大小寫差異 |
external | external | 無差異 |
footer | n/a | 不支持 |
format | format | 目前僅支持 "esm"。計劃支持 "cjs" 和 "iife"。 |
globalName | n/a | 不支持 |
ignoreAnnotations | n/a | 不支持 |
inject | n/a | 不支持 |
jsx | jsx | 在 JS API 中不支持,在 tsconfig.json 中配置 |
jsxDev | jsxDev | 在 JS API 中不支持,在 tsconfig.json 中配置 |
jsxFactory | jsxFactory | 在 JS API 中不支持,在 tsconfig.json 中配置 |
jsxFragment | jsxFragment | 在 JS API 中不支持,在 tsconfig.json 中配置 |
jsxImportSource | jsxImportSource | 在 JS API 中不支持,在 tsconfig.json 中配置 |
jsxSideEffects | jsxSideEffects | 在 JS API 中不支持,在 tsconfig.json 中配置 |
keepNames | n/a | 不支持 |
legalComments | n/a | 不支持 |
loader | loader | Bun 支持與 esbuild 不同的一組內置加載器;完整參考請參閱打包器 > 加載器。esbuild 加載器 dataurl、binary、base64、copy 和 empty 尚未實現。 |
logLevel | n/a | 不支持 |
logLimit | n/a | 不支持 |
logOverride | n/a | 不支持 |
mainFields | n/a | 不支持 |
mangleCache | n/a | 不支持 |
mangleProps | n/a | 不支持 |
mangleQuoted | n/a | 不支持 |
metafile | n/a | 不支持 |
minify | minify | 在 Bun 中,minify 可以是布爾值或對象。ts<br/>await Bun.build({<br/> entrypoints: ['./index.tsx'],<br/> // 啟用所有壓縮<br/> minify: true<br/><br/> // 細粒度選項<br/> minify: {<br/> identifiers: true,<br/> syntax: true,<br/> whitespace: true<br/> }<br/>})<br/> |
minifyIdentifiers | minify.identifiers | 請參閱 minify |
minifySyntax | minify.syntax | 請參閱 minify |
minifyWhitespace | minify.whitespace | 請參閱 minify |
nodePaths | n/a | 不支持 |
outExtension | n/a | 不支持 |
outbase | root | 不同的名稱 |
outdir | outdir | 無差異 |
outfile | outfile | 無差異 |
packages | n/a | 不支持,使用 external |
platform | target | 支持 "bun"、"node" 和 "browser"(默認)。不支持 "neutral"。 |
plugins | plugins | Bun 的插件 API 是 esbuild 的子集。一些 esbuild 插件可以直接與 Bun 一起工作。 |
preserveSymlinks | n/a | 不支持 |
publicPath | publicPath | 無差異 |
pure | n/a | 不支持 |
reserveProps | n/a | 不支持 |
resolveExtensions | n/a | 不支持 |
sourceRoot | n/a | 不支持 |
sourcemap | sourcemap | 支持 "inline"、"external" 和 "none" |
sourcesContent | n/a | 不支持 |
splitting | splitting | 無差異 |
stdin | n/a | 不支持 |
supported | n/a | 不支持 |
target | n/a | 不支持語法降級 |
treeShaking | n/a | 始終為 true |
tsconfig | n/a | 不支持 |
write | n/a | 如果設置了 outdir/outfile 則為 true,否則為 false |
插件 API
Bun 的插件 API 設計為與 esbuild 兼容。Bun 不支持 esbuild 的整個插件 API 表面,但實現了核心功能。許多第三方 esbuild 插件可以直接與 Bun 一起工作。
NOTE
長期來看,我們的目標是與 esbuild 的 API 功能對等,因此如果某些內容不起作用,請提交問題以幫助我們確定優先級。Bun 和 esbuild 中的插件使用構建器對象定義。
ts
import type { BunPlugin } from "bun";
const myPlugin: BunPlugin = {
name: "my-plugin",
setup(builder) {
// 定義插件
},
};構建器對象提供了一些方法用於掛鉤到打包過程的部分。Bun 實現了 onResolve 和 onLoad;它尚未實現 esbuild 鉤子 onStart、onEnd 和 onDispose,以及 resolve 工具。initialOptions 部分實現,為只讀且僅有 esbuild 選項的子集;請改用 config(相同但使用 Bun 的 BuildConfig 格式)。
ts
import type { BunPlugin } from "bun";
const myPlugin: BunPlugin = {
name: "my-plugin",
setup(builder) {
builder.onResolve(
{
/* onResolve.options */
},
args => {
return {
/* onResolve.results */
};
},
);
builder.onLoad(
{
/* onLoad.options */
},
args => {
return {
/* onLoad.results */
};
},
);
},
};onResolve
選項
- 🟢 `filter`
- 🟢 `namespace`
參數
- 🟢 `path`
- 🟢 `importer`
- 🔴 `namespace`
- 🔴 `resolveDir`
- 🔴 `kind`
- 🔴 `pluginData`
結果
- 🟢 `namespace`
- 🟢 `path`
- 🔴 `errors`
- 🔴 `external`
- 🔴 `pluginData`
- 🔴 `pluginName`
- 🔴 `sideEffects`
- 🔴 `suffix`
- 🔴 `warnings`
- 🔴 `watchDirs`
- 🔴 `watchFiles`
onLoad
選項
- 🟢 `filter`
- 🟢 `namespace`
參數
- 🟢 `path`
- 🔴 `namespace`
- 🔴 `suffix`
- 🔴 `pluginData`
結果
- 🟢 `contents`
- 🟢 `loader`
- 🔴 `errors`
- 🔴 `pluginData`
- 🔴 `pluginName`
- 🔴 `resolveDir`
- 🔴 `warnings`
- 🔴 `watchDirs`
- 🔴 `watchFiles`