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整理维护