執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

esbuild

從 esbuild 遷移到 Bun 的打包器指南

Bun 的打包器 API 深受 esbuild 啟發。本頁面對這兩個 API 進行了並列比較。

有一些行為有所不同:

效能

在 esbuild 的 three.js 基準測試中,Bun 的打包器速度比 esbuild 快 1.75 倍。

CLI API

terminal
# 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備註
--bundle不適用Bun 始終會進行打包;使用 --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" 和 "iife"。esbuild 預設為 "iife"。
--loader:.ext=loader--loader .ext:loaderBun 支援的內建載入器與 esbuild 不同;請參閱 載入器。esbuild 的載入器 dataurl、binary、base64、copy 和 empty 尚未實現。

--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。
--serve不適用不適用
--sourcemap--sourcemap支援 linked(未提供值時的預設值)、external、inline 和 none。不支援 esbuild 的 both。
--splitting--splitting無差異
--target不適用不支援。Bun 的打包器不會進行語法降級。
--watch--watch無差異
--allow-overwrite不適用Bun 從不允許覆蓋
--analyze不適用不支援
--asset-names--asset-naming為與 JS API 中的命名保持一致而重新命名
--banner--banner僅適用於 JS 包
--footer--footer僅適用於 JS 包
--certfile不適用不適用
--charset=utf8不適用不支援
--chunk-names--chunk-naming為與 JS API 中的命名保持一致而重新命名
--color不適用始終啟用
--drop--drop
不適用--featureBun 特有。通過 import { feature } from "bun:bundle" 啟用編譯時死程式碼消除的功能標誌
--entry-names--entry-naming為與 JS API 中的命名保持一致而重新命名
--global-name不適用不支援
--ignore-annotations--ignore-dce-annotations
--inject不適用不支援
--jsx--jsx-runtime <runtime>支援 "automatic"(使用 JSX 轉換)和 "classic"(使用 React.createElement)
--jsx-dev不適用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--jsx-side-effects
--keep-names--keep-names
--keyfile不適用不適用
--legal-comments不適用不支援
--log-level不適用不支援。可以在 bunfig.toml 中將日誌級別設定為 logLevel。
--log-limit不適用不支援
--log-override:X=Y不適用不支援
--main-fields不適用不支援
--mangle-cache不適用不支援
--mangle-props不適用不支援
--mangle-quoted不適用不支援
--metafile--metafile
--minify-whitespace--minify-whitespace
--minify-identifiers--minify-identifiers
--minify-syntax--minify-syntax
--out-extension不適用不支援
--outbase--root
--preserve-symlinks不適用不支援
--public-path--public-path
--pure不適用不支援
--reserve-props不適用不支援
--resolve-extensions不適用不支援
--servedir不適用不適用
--source-root不適用不支援
--sourcefile不適用不支援。Bun 不支援 stdin 輸入。
--sources-content不適用不支援
--supported不適用不支援
--tree-shaking不適用始終為 true。Bun 還會將 import() / require() 目標的匯出進行搖樹最佳化,僅保留匯入程式碼讀取的名稱(請參閱 程式碼拆分);esbuild 會保留動態匯入模組的所有匯出。
--tsconfig--tsconfig-override
--version不適用執行 bun --version 檢視 Bun 的版本。

JavaScript API

esbuild.build()Bun.build()備註
absWorkingDir不適用始終設定為 process.cwd()
alias不適用不支援
allowOverwrite不適用始終為 false
assetNamesnaming.asset使用與 esbuild 相同的模板語法,但必須明確包含 [ext]。

ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> asset: "[name].[ext]",<br/> },<br/>});<br/>
bannerbanner僅適用於 JS 包
bundle不適用始終為 true。使用 Bun.Transpiler 可在不打包的情況下進行轉譯。
charset不適用不支援
chunkNamesnaming.chunk使用與 esbuild 相同的模板語法,但必須明確包含 [ext]。

ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> naming: {<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/>
color不適用Bun 會在建置結果的 logs 屬性中傳回日誌。
conditionsconditions無差異
definedefine
dropdrop
entryNamesnaming 或 naming.entryBun 支援 naming 鍵,其值可以是字串或物件。使用與 esbuild 相同的模板語法,但必須明確包含 [ext]。

ts<br/>Bun.build({<br/> entrypoints: ["./index.tsx"],<br/> // when string, this is equivalent to entryNames<br/> naming: "[name].[ext]",<br/><br/> // granular naming options<br/> naming: {<br/> entry: "[name].[ext]",<br/> asset: "[name].[ext]",<br/> chunk: "[name].[ext]",<br/> },<br/>});<br/>
entryPointsentrypoints大小寫不同
externalexternal無差異
footerfooter僅適用於 JS 包
formatformat支援 "esm"、"cjs" 和 "iife"。
globalName不適用不支援
ignoreAnnotationsignoreDCEAnnotations
inject不適用不支援
jsxjsx.runtime支援 "automatic" 和 "classic"
jsxDevjsx.development
jsxFactoryjsx.factory
jsxFragmentjsx.fragment
jsxImportSourcejsx.importSource
jsxSideEffectsjsx.sideEffects
keepNamesminify.keepNames
legalComments不適用不支援
loaderloaderBun 支援的內建載入器與 esbuild 不同;請參閱 載入器。Bun 尚未實現 esbuild 的載入器 dataurl、binary、base64、copy 和 empty。
logLevel不適用不支援
logLimit不適用不支援
logOverride不適用不支援
mainFields不適用不支援
mangleCache不適用不支援
mangleProps不適用不支援
mangleQuoted不適用不支援
metafilemetafile
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
nodePaths不適用不支援
outExtension不適用不支援
outbaseroot名稱不同
outdiroutdir無差異
outfileoutfile無差異
packagespackages無差異
platformtarget支援 "bun"、"node" 和 "browser"(預設值)。不支援 "neutral"。
pluginspluginsBun 的外掛 API 是 esbuild 的子集。部分 esbuild 外掛無需修改即可與 Bun 配合使用。
preserveSymlinks不適用不支援
publicPathpublicPath無差異
pure不適用不支援
reserveProps不適用不支援
resolveExtensions不適用不支援
sourceRoot不適用不支援
sourcemapsourcemap支援 "none"、"linked"、"inline" 和 "external"
sourcesContent不適用不支援
splittingsplitting無差異
stdin不適用不支援
supported不適用不支援
target不適用不支援語法降級
treeShakingtreeShaking預設為 true
tsconfigtsconfig
write不適用設定了 outdir/outfile 時為 true,否則為 false

外掛 API

Bun 的外掛 API 旨在相容 esbuild。Bun 不支援 esbuild 的全部外掛 API,但實現了核心功能。許多第三方 esbuild 外掛無需修改即可與 Bun 配合使用。

在 Bun 和 esbuild 中,外掛都通過 builder 物件定義。

myPlugin.ts
import type { BunPlugin } from "bun";

const myPlugin: BunPlugin = {
  name: "my-plugin",
  setup(builder) {
    // 定義外掛
  },
};

builder 物件的方法可以掛接到打包流程的各個部分。Bun 實現了 onStart、onEnd、onResolve 和 onLoad;但沒有實現 esbuild 的鉤子 onDispose 和 resolve。Bun 部分實現了 initialOptions:該物件為只讀,僅公開 esbuild 選項的一個子集。請改用 config(Bun 的 BuildConfig 格式中具有相同功能的物件)。

myPlugin.ts
import type { BunPlugin } from "bun";
const myPlugin: BunPlugin = {
  name: "my-plugin",
  setup(builder) {
    builder.onStart(() => {
      /* 當打包開始時呼叫 */
    });
    builder.onResolve(
      {
        /* onResolve 選項 */
      },
      args => {
        return {
          /* onResolve 傳回值 */
        };
      },
    );
    builder.onLoad(
      {
        /* onLoad 選項 */
      },
      args => {
        return {
          /* onLoad 傳回值 */
        };
      },
    );
    builder.onEnd(result => {
      /* 當打包完成時呼叫 */
    });
  },
};

onResolve

  • 🟢 filter
  • 🟢 namespace

onLoad

  • 🟢 filter
  • 🟢 namespace