Bun

vs esbuild

Bun 的捆綁器 API 在很大程度上受到 esbuild 的啟發。從 esbuild 遷移到 Bun 的捆綁器應該相對輕鬆。本指南將簡要解釋您可能考慮遷移到 Bun 捆綁器的原因,並為那些已經熟悉 esbuild API 的人提供並排 API 比較參考。

有幾個行為差異需要注意。

  • 預設捆綁。與 esbuild 不同,Bun 始終預設捆綁。這就是為什麼 Bun 範例中不需要 --bundle 標誌的原因。若要個別轉譯每個檔案,請使用 Bun.Transpiler
  • 它只是一個捆綁器。與 esbuild 不同,Bun 的捆綁器不包含內建的開發伺服器或檔案監看器。它只是一個捆綁器。捆綁器旨在與 Bun.serve 和其他執行階段 API 結合使用,以達到相同的效果。因此,所有與 HTTP/檔案監看相關的選項均不適用。

效能

憑藉以效能為導向的 API 以及經過廣泛最佳化的基於 Zig 的 JS/TS 解析器,在 esbuild 的 three.js 基準測試中,Bun 的捆綁器比 esbuild 快 1.75 倍。

從頭開始捆綁 10 個 three.js 副本,包含來源地圖和最小化

CLI API

Bun 和 esbuild 都提供命令列介面。

esbuild <entrypoint> --outdir=out --bundle
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",但計畫支援更多模組格式。esbuild 預設為 "iife"

--loader:.ext=loader

--loader .ext:loader

Bun 支援與 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
--serve不適用不適用
--sourcemap--sourcemap沒有差異
--splitting--splitting沒有差異
--target不適用不支援。Bun 的捆綁器目前不執行任何語法降級。
--watch--watch沒有差異
--allow-overwrite不適用永遠不允許覆寫
--analyze不適用不支援
--asset-names--asset-naming為了與 JS API 中的 naming 一致性而重新命名
--banner--banner僅適用於 js 捆綁
--footer--footer僅適用於 js 捆綁
--certfile不適用不適用
--charset=utf8不適用不支援
--chunk-names--chunk-naming為了與 JS API 中的 naming 一致性而重新命名
--color不適用始終啟用
--drop--drop
--entry-names--entry-naming為了與 JS API 中的 naming 一致性而重新命名
--global-name不適用不適用,Bun 目前不支援 iife 輸出
--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。對於任何 Bun 都使用 jsxDEV。捆綁器不支援 preserve
--jsx-factory--jsx-factory
--jsx-fragment--jsx-fragment
--jsx-import-source--jsx-import-source
--jsx-side-effects不適用JSX 始終假定為無副作用
--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不適用不支援
--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 輸入。
--sourcemap--sourcemap沒有差異
--sources-content不適用不支援
--supported不適用不支援
--tree-shaking不適用始終為 true
--tsconfig--tsconfig-override
--version不適用執行 bun --version 以查看 Bun 的版本。

JavaScript API

esbuild.build()Bun.build()
absWorkingDir不適用始終設定為 process.cwd()
alias不適用不支援
allowOverwrite不適用始終為 false

assetNames

naming.asset

使用與 esbuild 相同的範本語法,但 [ext] 必須明確包含。

Bun.build({
  entrypoints: ["./index.tsx"],
  naming: {
    asset: "[name].[ext]",
  },
});
banner不適用不支援
bundle不適用始終為 true。使用 Bun.Transpiler 在不捆綁的情況下進行轉譯。
charset不適用不支援

chunkNames

naming.chunk

使用與 esbuild 相同的範本語法,但 [ext] 必須明確包含。

Bun.build({
  entrypoints: ["./index.tsx"],
  naming: {
    chunk: "[name].[ext]",
  },
});
color不適用Bun 在建置結果的 logs 屬性中傳回記錄。
conditions不適用不支援。匯出條件優先順序由 target 決定。
definedefine
drop不適用不支援

entryNames

namingnaming.entry

Bun 支援 naming 鍵,它可以是字串或物件。使用與 esbuild 相同的範本語法,但 [ext] 必須明確包含。

Bun.build({
  entrypoints: ["./index.tsx"],
  // when string, this is equivalent to entryNames
  naming: "[name].[ext]",

  // granular naming options
  naming: {
    entry: "[name].[ext]",
    asset: "[name].[ext]",
    chunk: "[name].[ext]",
  },
});
entryPointsentrypoints大小寫差異
externalexternal沒有差異
頁尾不適用不支援
格式格式目前僅支援 "esm"。計畫支援 "cjs""iife"
globalName不適用不支援
ignoreAnnotations不適用不支援
inject不適用不支援
jsxjsxJS API 中不支援,請在 tsconfig.json 中設定
jsxDevjsxDevJS API 中不支援,請在 tsconfig.json 中設定
jsxFactoryjsxFactoryJS API 中不支援,請在 tsconfig.json 中設定
jsxFragmentjsxFragmentJS API 中不支援,請在 tsconfig.json 中設定
jsxImportSourcejsxImportSourceJS API 中不支援,請在 tsconfig.json 中設定
jsxSideEffectsjsxSideEffectsJS API 中不支援,請在 tsconfig.json 中設定
keepNames不適用不支援
legalComments不適用不支援
loaderloaderBun 支援與 esbuild 不同的一組內建載入器;如需完整參考,請參閱捆綁器 > 載入器。esbuild 載入器 dataurlbinarybase64copyempty 尚未實作。
logLevel不適用不支援
logLimit不適用不支援
logOverride不適用不支援
mainFields不適用不支援
mangleCache不適用不支援
mangleProps不適用不支援
mangleQuoted不適用不支援
metafile不適用不支援

minify

minify

在 Bun 中,minify 可以是布林值或物件。

await Bun.build({
  entrypoints: ['./index.tsx'],
  // enable all minification
  minify: true

  // granular options
  minify: {
    identifiers: true,
    syntax: true,
    whitespace: true
  }
})
minifyIdentifiersminify.identifiers參見 minify
minifySyntaxminify.syntax參見 minify
minifyWhitespaceminify.whitespace參見 minify
nodePaths不適用不支援
outExtension不適用不支援
outbaseroot不同名稱
outdiroutdir沒有差異
outfileoutfile沒有差異
packages不適用不支援,請使用 external
platformtarget支援 "bun""node""browser" (預設值)。不支援 "neutral"
pluginspluginsBun 的插件 API 是 esbuild 的子集。一些 esbuild 插件可以直接與 Bun 搭配使用。
preserveSymlinks不適用不支援
publicPathpublicPath沒有差異
pure不適用不支援
reserveProps不適用不支援
resolveExtensions不適用不支援
sourceRoot不適用不支援
sourcemapsourcemap支援 "inline""external""none"
sourcesContent不適用不支援
splittingsplitting沒有差異
stdin不適用不支援
supported不適用不支援
target不適用不支援語法降級
treeShaking不適用始終為 true
tsconfig不適用不支援
write不適用如果設定了 outdir/outfile,則設定為 true,否則為 false

插件 API

Bun 的插件 API 設計為與 esbuild 相容。Bun 不支援 esbuild 的整個插件 API 介面,但核心功能已實作。許多第三方 esbuild 插件可以直接與 Bun 搭配使用。

長期而言,我們的目標是與 esbuild 的 API 達到功能對等,因此如果有些東西無法運作,請提交 issue 以協助我們排定優先順序。

Bun 和 esbuild 中的插件是使用 builder 物件定義的。

import type { BunPlugin } from "bun";

const myPlugin: BunPlugin = {
  name: "my-plugin",
  setup(builder) {
    // define plugin
  },
};

builder 物件提供了一些方法,用於掛鉤到捆綁過程的各個部分。Bun 實作了 onResolveonLoad;它尚未實作 esbuild 的鉤子 onStartonEndonDispose,以及 resolve 工具。initialOptions 已部分實作,為唯讀且僅具有 esbuild 選項的子集;請改用 config (相同的事物,但使用 Bun 的 BuildConfig 格式)。

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

引數

🟢路徑
🟢導入器
🔴namespace
🔴resolveDir
🔴kind
🔴pluginData

結果

🟢namespace
🟢路徑
🔴錯誤
🔴external
🔴pluginData
🔴pluginName
🔴sideEffects
🔴suffix
🔴警告
🔴watchDirs
🔴watchFiles

onLoad

選項

🟢filter
🟢namespace

引數

🟢路徑
🔴namespace
🔴suffix
🔴pluginData

結果

🟢內容
🟢loader
🔴錯誤
🔴pluginData
🔴pluginName
🔴resolveDir
🔴警告
🔴watchDirs
🔴watchFiles