Bun 的捆绑器实现了一个 --compile
标志,用于从 TypeScript 或 JavaScript 文件生成一个独立的二进制文件。
bun build ./cli.ts --compile --outfile mycli
console.log("Hello world!");
这会将 cli.ts
捆绑到一个可直接执行的可执行文件中
$ ./mycli
Hello world!
所有导入的文件和包都捆绑到可执行文件中,以及 Bun 运行时的副本。支持所有内置的 Bun 和 Node.js API。
交叉编译到其他平台
--target
标志允许你为与运行 bun build
的机器不同的操作系统、架构或 Bun 版本编译你的独立可执行文件。
为 Linux x64(大多数服务器)构建
bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp
# To support CPUs from before 2013, use the baseline version (nehalem)
bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp
# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
# modern is faster, but baseline is more compatible.
bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp
为 Linux ARM64(例如 Graviton 或 Raspberry Pi)构建
# Note: the default architecture is x64 if no architecture is specified.
bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp
为 Windows x64 构建
bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp
# To support CPUs from before 2013, use the baseline version (nehalem)
bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp
# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
bun build --compile --target=bun-windows-x64-modern ./path/to/my/app.ts --outfile myapp
# note: if no .exe extension is provided, Bun will automatically add it for Windows executables
为 macOS arm64 构建
bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp
为 macOS x64 构建
bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp
支持的目标
--target
标志的顺序无关紧要,只要它们以 -
分隔即可。
--target | 操作系统 | 架构 | 现代 | 基线 |
---|---|---|---|---|
bun-linux-x64 | Linux | x64 | ✅ | ✅ |
bun-linux-arm64 | Linux | arm64 | ✅ | N/A |
bun-windows-x64 | Windows | x64 | ✅ | ✅ |
Windows | arm64 | ❌ | ❌ | |
bun-darwin-x64 | macOS | x64 | ✅ | ✅ |
bun-darwin-arm64 | macOS | arm64 | ✅ | N/A |
在 x64 平台上,Bun 使用 SIMD 优化,该优化需要支持 AVX2 指令的现代 CPU。Bun 的 -baseline
构建适用于不支持这些优化的旧 CPU。通常,当您安装 Bun 时,我们会自动检测要使用哪个版本,但由于您可能不知道目标 CPU,因此在交叉编译时可能更难做到这一点。您通常不必担心 Darwin x64,但它与 Windows x64 和 Linux x64 相关。如果您或您的用户看到 "Illegal instruction"
错误,您可能需要使用基准版本。
部署到生产环境
编译的可执行文件减少了内存使用量并缩短了 Bun 的启动时间。
通常,Bun 在 import
和 require
时读取和转换 JavaScript 和 TypeScript 文件。这是 Bun “正常工作” 的一部分,但它不是免费的。从磁盘读取文件、解析文件路径、解析、转换和打印源代码需要时间和内存。
使用编译的可执行文件,您可以将该成本从运行时转移到构建时。
在部署到生产环境时,我们建议执行以下操作
bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp
这些标志有什么作用?
--minify
参数优化了转换后输出代码的大小。如果您有一个大型应用程序,这可以节省数兆字节的空间。对于较小的应用程序,它可能仍然会稍微缩短启动时间。
--sourcemap
参数嵌入了使用 zstd 压缩的源代码映射,以便错误和堆栈跟踪指向其原始位置,而不是转换后的位置。当发生错误时,Bun 会自动解压缩和解析源代码映射。
SQLite
您可以将 bun:sqlite
导入与 bun build --compile
一起使用。
默认情况下,数据库相对于进程的当前工作目录进行解析。
import db from "./my.db" with { type: "sqlite" };
console.log(db.query("select * from users LIMIT 1").get());
这意味着如果可执行文件位于 /usr/bin/hello
,用户的终端位于 /home/me/Desktop
,它将查找 /home/me/Desktop/my.db
。
$ cd /home/me/Desktop
$ ./hello
嵌入资产和文件
独立的可执行文件支持嵌入文件。
要使用 bun build --compile
将文件嵌入到可执行文件中,请在代码中导入该文件
// this becomes an internal file path
import icon from "./icon.png" with { type: "file" };
import { file } from "bun";
export default {
fetch(req) {
// Embedded files can be streamed from Response objects
return new Response(file(icon));
},
};
可以使用 Bun.file
的函数或 Node.js 的 fs.readFile
函数(在 "node:fs"
中)来读取嵌入的文件。
例如,要读取嵌入文件的内容
import icon from "./icon.png" with { type: "file" };
import { file } from "bun";
const bytes = await file(icon).arrayBuffer();
嵌入 SQLite 数据库
如果您的应用程序想要嵌入 SQLite 数据库,请在 import 属性中设置 type: "sqlite"
,并将 embed
属性设置为 "true"
。
import myEmbeddedDb from "./my.db" with { type: "sqlite", embed: "true" };
console.log(myEmbeddedDb.query("select * from users LIMIT 1").get());
此数据库是可读写的,但当可执行文件退出时,所有更改都将丢失(因为它存储在内存中)。
嵌入 N-API 插件
从 Bun v1.0.23 开始,您可以将 .node
文件嵌入到可执行文件中。
const addon = require("./addon.node");
console.log(addon.hello());
不幸的是,如果您使用 @mapbox/node-pre-gyp
或其他类似工具,则需要确保直接需要 .node
文件,否则它将无法正确捆绑。
缩小
要稍微减小可执行文件的大小,请将 --minify
传递给 bun build --compile
。这使用 Bun 的缩小器来减小代码大小。不过,总体而言,Bun 的二进制文件仍然太大,我们需要使其更小。
不支持的 CLI 参数
目前,--compile
标志一次只能接受一个入口点,并且不支持以下标志
--outdir
— 改用outfile
。--splitting
--public-path
--target=node
或--target=browser
--format
- 始终输出二进制可执行文件。在内部,它几乎是 esm。--no-bundle
- 我们始终将所有内容捆绑到可执行文件中。