Skip to content

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

esbuildbun build注釋
--bundlen/aBun 始終打包,使用 --no-bundle 禁用此行為。
--define:K=V--define K=V小的語法差異;無冒號。
esbuild --define:foo=bar
bun build --define foo=bar
--external:<pkg>--external <pkg>小的語法差異;無冒號。
esbuild --external:react
bun build --external react
--format--formatBun 目前支持 "esm""cjs",但計劃支持更多模塊格式。esbuild 默認為 "iife"
--loader:.ext=loader--loader .ext:loaderBun 支持與 esbuild 不同的一組內置加載器;完整參考請參閱打包器 > 加載器。esbuild 加載器 dataurlbinarybase64copyempty 尚未實現。

--loader 的語法略有不同。
esbuild app.ts --bundle --loader:.svg=text
bun build app.ts --loader .svg:text
--minify--minify無差異
--outdir--outdir無差異
--outfile--outfile無差異
--packages--packages無差異
--platform--target為與 tsconfig 保持一致而重命名為 --target。不支持 neutral
--serven/a不適用
--sourcemap--sourcemap無差異
--splitting--splitting無差異
--targetn/a不支持。Bun 的打包器此時不執行語法降級。
--watch--watch無差異
--allow-overwriten/a不允許覆蓋
--analyzen/a不支持
--asset-names--asset-naming為與 JS API 中的 naming 保持一致而重命名
--banner--banner僅適用於 js 打包
--footer--footer僅適用於 js 打包
--certfilen/a不適用
--charset=utf8n/a不支持
--chunk-names--chunk-naming為與 JS API 中的 naming 保持一致而重命名
--colorn/a始終啟用
--drop--drop
--entry-names--entry-naming為與 JS API 中的 naming 保持一致而重命名
--global-namen/a不適用,Bun 此時不支持 iife 輸出
--ignore-annotations--ignore-dce-annotations
--injectn/a不支持
--jsx--jsx-runtime <runtime>支持 "automatic"(使用 jsx 轉換)和 "classic"(使用 React.createElement
--jsx-devn/aBun 從 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-effectsn/aJSX 始終假定為無副作用
--keep-namesn/a不支持
--keyfilen/a不適用
--legal-commentsn/a不支持
--log-leveln/a不支持。這可以在 bunfig.toml 中設置為 logLevel
--log-limitn/a不支持
--log-override:X=Yn/a不支持
--main-fieldsn/a不支持
--mangle-cachen/a不支持
--mangle-propsn/a不支持
--mangle-quotedn/a不支持
--metafilen/a不支持
--minify-whitespace--minify-whitespace
--minify-identifiers--minify-identifiers
--minify-syntax--minify-syntax
--out-extensionn/a不支持
--outbase--root
--preserve-symlinksn/a不支持
--public-path--public-path
--puren/a不支持
--reserve-propsn/a不支持
--resolve-extensionsn/a不支持
--servedirn/a不適用
--source-rootn/a不支持
--sourcefilen/a不支持。Bun 尚不支持 stdin 輸入。
--sourcemap--sourcemap無差異
--sources-contentn/a不支持
--supportedn/a不支持
--tree-shakingn/a始終為 true
--tsconfig--tsconfig-override
--versionn/a運行 bun --version 查看 Bun 版本。

JavaScript API

esbuild.build()Bun.build()注釋
absWorkingDirn/a始終設置為 process.cwd()
aliasn/a不支持
allowOverwriten/a始終為 false
assetNamesnaming.asset使用與 esbuild 相同的模板語法,但必須顯式包含 [ext]

ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> asset: "[name].[ext]",<br/> },<br/>});<br/>
bannern/a不支持
bundlen/a始終為 true。使用 Bun.Transpiler 轉譯而不打包。
charsetn/a不支持
chunkNamesnaming.chunk使用與 esbuild 相同的模板語法,但必須顯式包含 [ext]

ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/>
colorn/aBun 在構建結果的 logs 屬性中返回日志。
conditionsn/a不支持。導出條件優先級由 target 確定。
definedefine
dropn/a不支持
entryNamesnamingnaming.entryBun 支持可以是字符串或對象的 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/>
entryPointsentrypoints大小寫差異
externalexternal無差異
footern/a不支持
formatformat目前僅支持 "esm"。計劃支持 "cjs""iife"
globalNamen/a不支持
ignoreAnnotationsn/a不支持
injectn/a不支持
jsxjsx在 JS API 中不支持,在 tsconfig.json 中配置
jsxDevjsxDev在 JS API 中不支持,在 tsconfig.json 中配置
jsxFactoryjsxFactory在 JS API 中不支持,在 tsconfig.json 中配置
jsxFragmentjsxFragment在 JS API 中不支持,在 tsconfig.json 中配置
jsxImportSourcejsxImportSource在 JS API 中不支持,在 tsconfig.json 中配置
jsxSideEffectsjsxSideEffects在 JS API 中不支持,在 tsconfig.json 中配置
keepNamesn/a不支持
legalCommentsn/a不支持
loaderloaderBun 支持與 esbuild 不同的一組內置加載器;完整參考請參閱打包器 > 加載器。esbuild 加載器 dataurlbinarybase64copyempty 尚未實現。
logLeveln/a不支持
logLimitn/a不支持
logOverriden/a不支持
mainFieldsn/a不支持
mangleCachen/a不支持
manglePropsn/a不支持
mangleQuotedn/a不支持
metafilen/a不支持
minifyminify在 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/>
minifyIdentifiersminify.identifiers請參閱 minify
minifySyntaxminify.syntax請參閱 minify
minifyWhitespaceminify.whitespace請參閱 minify
nodePathsn/a不支持
outExtensionn/a不支持
outbaseroot不同的名稱
outdiroutdir無差異
outfileoutfile無差異
packagesn/a不支持,使用 external
platformtarget支持 "bun""node""browser"(默認)。不支持 "neutral"
pluginspluginsBun 的插件 API 是 esbuild 的子集。一些 esbuild 插件可以直接與 Bun 一起工作。
preserveSymlinksn/a不支持
publicPathpublicPath無差異
puren/a不支持
reservePropsn/a不支持
resolveExtensionsn/a不支持
sourceRootn/a不支持
sourcemapsourcemap支持 "inline""external""none"
sourcesContentn/a不支持
splittingsplitting無差異
stdinn/a不支持
supportedn/a不支持
targetn/a不支持語法降級
treeShakingn/a始終為 true
tsconfign/a不支持
writen/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 實現了 onResolveonLoad;它尚未實現 esbuild 鉤子 onStartonEndonDispose,以及 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`

Bun學習網由www.bunjs.com.cn整理維護