首页 / Bun 入门教程 / 压缩与独立可执行文件

Bun 入门教程

压缩与独立可执行文件

本教程共 34 篇 · 第 19 篇 · 更新于 2026-08-06

Bun打包器压缩Minify可执行文件Compile

本节目标:

  • 掌握 --minify 及其粒度标志,理解 tree-shaking 与 /*@__PURE__*/
  • 理解 targetsourcemap 在产物优化与调试中的作用
  • 重点掌握 bun build --compile 生成独立可执行文件
  • 了解跨平台 target、内嵌资源与部署推荐参数

当一个项目从”能跑”走向”要上线”,产物体积、运行便捷性、可调试性就成了硬指标。Bun 打包器把这些能力都内置了:一行 --minify 即可压缩代码;一个 --compile 就能把整个应用连同 Bun 运行时打包成单个二进制文件,发给没有 Bun 的机器也能直接运行。本章先讲压缩与调试,再深入独立可执行文件。

19.1 压缩(Minify)

压缩的目标是减小产物体积、提升加载/执行速度。Bun 的压缩器支持三种可独立开关的模式:

  • whitespace:移除空白与冗余换行;
  • syntax:做语法层面的等价转换(如简化布尔表达式、常量折叠);
  • identifiers:把局部变量名重命名为更短的名字(如 userNamea)。

--minify 一次性开启全部三种;你也可以只开其中一部分:

# 全部开启(最常用)
bun build ./src/index.ts --outfile ./dist/app.js --minify

# 只做语法/空白压缩,保留变量名(便于排查线上问题)
bun build ./src/index.ts --outfile ./dist/app.js --minify-whitespace --minify-syntax

# 完整压缩 + 保留函数名(便于错误栈可读)
bun build ./src/index.ts --outfile ./dist/app.js --minify --keep-names
Note

还有一个便捷开关 --production,它等价于”开启压缩并应用生产环境的若干默认行为”。在 CI 或发布脚本里用 --production 比手写一串 --minify-* 更省心。

19.1.1 丢弃与保留

除了压缩,Bun 还提供”丢弃”类开关来进一步瘦身:

  • --drop=console:移除所有 console.* 调用,避免生产环境泄露调试日志;
  • --drop=debugger:移除 debugger 语句;
  • --keep-names:即便开了 identifiers 重命名,也保留函数/类名字,让错误栈仍可读。
# 生产构建:压缩 + 去掉 console/debugger + 保留名字
bun build ./src/index.ts --outfile ./dist/app.js --minify --drop=console --drop=debugger --keep-names

19.2 Tree-shaking 与 /*@__PURE__*/

Bun 打包器默认做 tree-shaking:没有被任何代码路径用到的导出,会被静态分析后剔除,不会进入产物。要让 tree-shaking 更可靠,可以在”无副作用”的函数调用前加 /*@__PURE__*/ 注释,告诉压缩器”这个调用如果结果没被使用,就可以安全删除”:

// 若 myHelper 的返回值没被使用,整行可被安全移除
/*@__PURE__*/ myHelper();
Warning

tree-shaking 依赖”静态可分析性”。如果你用 eval、动态 import(variable)、或给模块挂载全局副作用且无法被证明无影响,相关代码可能被保守地保留下来。保持导入/导出静态、明确,是让 tree-shaking 生效的前提。

19.3 target 与 sourcemap

target

上一章讲过 target 决定运行环境(browser/bun/node)。这里补充一点:target 也会影响语法降级程度——面向更老环境时,Bun 会把新语法(如某些 ES2022 特性)转成更兼容的写法。把它和压缩组合使用,是生产构建的常规操作。

sourcemap

压缩后源码可读性极差,排错需要 sourcemap(源码映射)。Bun 支持四种模式:

  • none:不生成(默认);
  • linked:生成独立 .js.map 文件并让产物引用它;
  • inline:把映射以 data URI 形式内联进产物;
  • external:生成映射但不自动关联到产物(用于自定义管理)。
# 生成独立 sourcemap,出问题时能回溯到原始源码
bun build ./src/index.ts --outfile ./dist/app.js --minify --sourcemap=linked
Tip

生产环境推荐 linked 而非 inline:映射单独成文件,不会撑大主产物;同时把 .map 仅对内部可访问,避免泄露源码结构。

19.4 独立可执行文件:bun build --compile

这是本章的重头戏。普通 bun build 产出的是”需要 Bun/Node 才能跑的 JS 文件”;而 --compile 会把你的代码连同 Bun 运行时本身一起打包,生成一个单一二进制文件。拿到这个文件的机器,即便没装 Bun,也能直接执行。

最基础的用法:

bun build ./src/index.ts --compile --outfile ./myapp

执行后当前目录会出现一个 myapp(在 Windows 上是 myapp.exe)。把它拷到任何同架构的机器上,./myapp 即可运行,无需安装任何依赖。

如果你的入口带 shebang(#!/usr/bin/env bun),--compile 会把它当作可执行脚本处理,生成的二进制天然可直接运行。

19.4.1 在 JS API 中使用

await Bun.build({
  entrypoints: ["./src/cli.ts"],
  compile: {
    outfile: "./myapp",
    target: "bun-linux-x64",
  },
});

compile 是一个对象,里面可以指定 outfile(输出路径)和 target(目标平台,见下文)。

19.4.2 跨平台 target

--compile 默认编译”当前运行平台”的二进制。但你也可以显式指定 target,实现交叉编译,例如在一台 macOS 上产出 Windows 可执行文件。常见 target 形如:

  • bun-linux-x64 / bun-linux-arm64(含 -musl 变体用于 Alpine 等);
  • bun-windows-x64
  • bun-darwin-arm64 / bun-darwin-x64
  • 另有 -baseline(兼容更老 CPU)与 -modern(面向新 CPU 优化)后缀变体。
# 在任意平台上,一键产出 Windows 64 位可执行文件
bun build ./src/index.ts --compile --target=bun-windows-x64 --outfile ./myapp.exe
Note

交叉编译生成的是”该平台的二进制”,但功能特性以你的 Bun 版本为准。部署前请务必在目标平台上实跑一遍,确认行为与本地一致。

19.4.3 部署推荐参数

推荐的发布命令组合是:--compile 配合 --minify--sourcemap,必要时加 --bytecode

bun build ./src/index.ts --compile --minify --sourcemap --outfile ./myapp
  • --minify 缩小体积;
  • --sourcemap 保留排错能力;
  • --bytecode 把 JS 预编译为字节码,既能略微减小体积,也能让启动更快、并避免源码被轻易反编译(注意:字节码并非强加密,仅增加逆向门槛)。

19.4.4 内嵌资源与数据

独立可执行文件同样能携带资源。用 with { type: "file" } 导入的文件会被打包进二进制内部,运行时 import 得到的是可读取的内容:

import icon from "./icon.png" with { type: "file" };
// 在可执行文件里,icon 仍可正常被读取,无需外部文件

同理,with { type: "sqlite" } 可以把 SQLite 数据库嵌入产物(target=bun),随可执行文件一起分发。Bun 还提供 Bun.isStandaloneExecutable 判断当前是否以独立可执行文件运行,以及 Bun.embeddedFiles 访问内嵌文件列表。

Warning

--compile 时,部分依赖”运行时动态读取外部路径”的逻辑可能失效,因为打包后文件已内嵌、不再以散落文件形式存在。如果你依赖读取脚本同目录下的配置文件,请改用内嵌资源或运行时参数传入。

19.4.5 运行参数与配置

编译出的二进制在被调用时,仍可接收 Bun 的运行参数。你可以用 --compile-exec-argv 预设一组 argv,或通过环境变量 BUN_OPTIONS 注入运行时选项。Bun 还会默认加载 .envbunfig.toml 中的相关配置(独立可执行场景下这部分默认开启,便于携带配置)。

此外,--define 可在编译期把常量替换成固定值(类似”编译期宏”),--splitting 支持代码分割。生产部署常见组合是 --compile --minify --sourcemap,再加可选的 --bytecode

19.5 压缩与可执行文件的关系

需要厘清:--minify 等压缩选项同样适用于 --compile。也就是说,你既可以”压缩出一份小 JS”给有 Bun 的环境,也可以”压缩 + 编译成单文件二进制”直接分发。二者的差别只在于最终产物是否需要运行时不场。

Tip

选型建议:内部服务器/容器里本来就有 Bun,用普通 bun build --minify 即可;要给外部用户一个”双击就能跑”的工具、或做无依赖的分发,才用 --compile。不要为了”看起来更高级”而盲目编译——它会增加构建体积与构建时间。

19.6 小结

本章我们覆盖了产物优化与分发的关键能力:

  • 压缩三模式(whitespace/syntax/identifiers)可由 --minify 一键开启或分别控制;
  • --drop=console/debugger 进一步瘦身,--keep-names 保留可读性;
  • tree-shaking 默认开启,/*@__PURE__*/ 标注无副作用调用可提升剔除效果;
  • target 控制语法降级,sourcemap(linked/inline/external)用于排错;
  • 重头戏 --compile 把代码与 Bun 运行时打包成单文件二进制,target 支持跨平台编译,推荐搭配 --minify --sourcemap [--bytecode]
  • 资源可用 type: "file" / sqlite / --asset 内嵌进可执行文件。

把应用压缩好、打包成单文件后,下一章我们来看 Bun 在”前端 HTML 入口”与”全栈开发服务器”上的玩法,把打包器接入真实的全栈开发流程。