Bun 的打包器支持 --compile 标志,用于从 TypeScript 或 JavaScript 文件生成独立的二进制可执行文件。
bun build ./cli.ts --compile --outfile mycli
build.ts await Bun. build ({
entrypoints : [ " ./cli.ts " ],
compile : {
outfile : " ./mycli " ,
},
});
cli.ts console. log ( " Hello world! " );
这会将 cli.ts 打包成一个可以直接执行的二进制文件:
所有导入的文件和包都会被打包进可执行文件中,同时包含一份 Bun 运行时。所有内置的 Bun 和 Node.js API 都被支持。
跨平台交叉编译
--target 标志允许你为与执行 bun build 的机器不同的操作系统、架构或 Bun 版本编译独立可执行文件。
构建 Linux x64 版本(大多数服务器):
bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp
# 支持 2013 年以前的 CPU,使用 baseline 版本(nehalem)
bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp
# 仅支持 2013 年及之后的 CPU,使用 modern 版本(haswell)
# modern 版本速度更快,但 baseline 兼容性更广。
bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp
build.ts // 标准 Linux x64
await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
target : " bun-linux-x64 " ,
outfile : " ./myapp " ,
},
});
// Baseline (2013 年前 CPU)
await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
target : " bun-linux-x64-baseline " ,
outfile : " ./myapp " ,
},
});
// Modern (2013 年及以后 CPU, 更快)
await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
target : " bun-linux-x64-modern " ,
outfile : " ./myapp " ,
},
});
构建 Linux ARM64 版本(如 Graviton 或 Raspberry Pi):
# 注意:默认架构为 x64,如果未指定架构。
bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
target : " bun-linux-arm64 " ,
outfile : " ./myapp " ,
},
});
构建 Windows x64 版本:
bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp
# 支持 2013 年以前的 CPU,使用 baseline 版本(nehalem)
bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp
# 仅支持 2013 年及以后 CPU,使用 modern 版本(haswell)
bun build --compile --target=bun-windows-x64-modern ./path/to/my/app.ts --outfile myapp
# 注意:如果不提供 .exe 后缀,Bun 会自动为 Windows 可执行文件加上
build.ts // 标准 Windows x64
await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
target : " bun-windows-x64 " ,
outfile : " ./myapp " , // 自动加 .exe 后缀
},
});
// Baseline 或 modern 版本
await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
target : " bun-windows-x64-baseline " ,
outfile : " ./myapp " ,
},
});
为 Windows arm64 构建:
bun build --compile --target=bun-windows-arm64 ./path/to/my/app.ts --outfile myapp
# note: if no .exe extension is provided, Bun will automatically add it for Windows executables
build.ts await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
target : " bun-windows-arm64 " ,
outfile : " ./myapp " , // .exe added automatically
},
});
构建 macOS arm64 版本:
bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
target : " bun-darwin-arm64 " ,
outfile : " ./myapp " ,
},
});
构建 macOS x64 版本:
bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
target : " bun-darwin-x64 " ,
outfile : " ./myapp " ,
},
});
支持的目标平台
--target 标志的顺序无关紧要,只要用 - 分隔即可。
—target 操作系统 架构 现代架构 基线架构 Libc bun-linux-x64 Linux x64 ✅ ✅ glibc bun-linux-arm64 Linux arm64 ✅ N/A glibc bun-windows-x64 Windows x64 ✅ ✅ - bun-windows-arm64 Windows arm64 ✅ N/A - bun-darwin-x64 macOS x64 ✅ ✅ - bun-darwin-arm64 macOS arm64 ✅ N/A - bun-linux-x64-musl Linux x64 ✅ ✅ musl bun-linux-arm64-musl Linux arm64 ✅ N/A musl
在 x64 平台上,Bun 使用 SIMD 优化,需要支持 AVX2 指令的现代 CPU。-baseline 版本用于不支持这些优化的老 CPU。通常安装
Bun 时会自动检测使用哪个版本,但交叉编译时较难判断目标 CPU。Darwin x64 通常无须担心,但 Windows 和 Linux x64
则可能遇到 "Illegal instruction" 错误,可能需要使用 baseline 版本。
编译时常量
使用 --define 标志可将编译时常量注入可执行文件,例如版本号、构建时间戳或配置值:
bun build --compile --define BUILD_VERSION= ' "1.2.3" ' --define BUILD_TIME= ' "2024-01-15T10:30:00Z" ' src/cli.ts --outfile mycli
build.ts await Bun. build ({
entrypoints : [ " ./src/cli.ts " ],
compile : {
outfile : " ./mycli " ,
},
define : {
BUILD_VERSION : JSON . stringify ( " 1.2.3 " ),
BUILD_TIME : JSON . stringify ( " 2024-01-15T10:30:00Z " ),
},
});
这些常量会在编译时直接嵌入二进制文件中,无运行时开销,还可以触发死代码消除优化。
生产环境部署
编译后的可执行文件降低内存使用并提升 Bun 启动速度。
通常,Bun 会在 import 和 require 时读取并转译 JavaScript 和 TypeScript 文件。这让 Bun 使用非常便利,但需要耗费时间和内存去读取磁盘文件、解析路径、解析和转译源代码。
通过生成编译后的可执行文件,可以将这些开销从运行时转移到构建时。
部署到生产环境推荐做法:
bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
outfile : " ./myapp " ,
},
minify : true ,
sourcemap : " linked " ,
});
字节码编译
为提升启动速度,启用字节码编译:
bun build --compile --minify --sourcemap --bytecode ./path/to/my/app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./path/to/my/app.ts " ],
compile : {
outfile : " ./myapp " ,
},
minify : true ,
sourcemap : " linked " ,
bytecode : true ,
});
使用字节码编译,tsc 启动速度提升两倍:
字节码编译将大文件的解析开销从运行时转移到打包时,提升了启动速度,但稍微增加了 bun build 命令的时长,不影响源码可读性。
字节码编译在搭配 --compile 时同时支持 cjs 和 esm 格式。
各个标志的作用
--minify 用于优化转译输出代码的体积,体积较大的应用可节省数 MB 空间,较小应用也可能稍微加快启动。
--sourcemap 生成用 zstd 压缩的 sourcemap,让错误和堆栈跟踪指向原始代码位置。Bun 会在错误发生时自动解压和解析 sourcemap。
--bytecode 激活字节码编译。Bun 内部的 JavaScriptCore 引擎会将 JS 源码编译成字节码,启用此选项可在构建时提前完成编译,从而缩短启动时间。
嵌入运行时参数
--compile-exec-argv="args" — 嵌入运行时参数,通过 process.execArgv 可访问:
bun build --compile --compile-exec-argv= " --smol --user-agent=MyBot " ./app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./app.ts " ],
compile : {
execArgv : [ " --smol " , " --user-agent=MyBot " ],
outfile : " ./myapp " ,
},
});
app.ts // 编译后的程序中
console. log (process.execArgv); // ["--smol", "--user-agent=MyBot"]
通过 BUN_OPTIONS 传入运行时参数
BUN_OPTIONS 环境变量适用于独立可执行文件,允许你传入运行时标志,而无需重新编译:
# 在编译后的可执行文件上启用 CPU 性能分析
BUN_OPTIONS = " --cpu-prof " ./myapp
# 启用堆性能分析并输出 markdown 格式
BUN_OPTIONS = " --heap-prof-md " ./myapp
# 组合多个标志
BUN_OPTIONS = " --smol --cpu-prof-md " ./myapp
此功能适合调试或分析生产环境下的可执行文件,无需重新构建。
自动加载配置
独立可执行文件可以自动从运行目录加载配置文件。默认:
禁用 加载 tsconfig.json 和 package.json — 这些通常只在开发时需要,编译时已经用过了
启用 加载 .env 和 bunfig.toml — 这些通常包含运行时配置,部署时可能有所不同
未来版本中,为了更确定的行为,可能会默认禁用 .env 和 bunfig.toml 加载。
运行时启用配置加载
如果你的可执行文件需要运行时读取 tsconfig.json 或 package.json,可使用新的 CLI 标志开启:
# 启用 tsconfig.json 运行时加载
bun build --compile --compile-autoload-tsconfig ./app.ts --outfile myapp
# 启用 package.json 运行时加载
bun build --compile --compile-autoload-package-json ./app.ts --outfile myapp
# 同时启用
bun build --compile --compile-autoload-tsconfig --compile-autoload-package-json ./app.ts --outfile myapp
运行时禁用配置加载
要禁用 .env 或 bunfig.toml 以实现确定性执行:
# 禁用 .env 加载
bun build --compile --no-compile-autoload-dotenv ./app.ts --outfile myapp
# 禁用 bunfig.toml 加载
bun build --compile --no-compile-autoload-bunfig ./app.ts --outfile myapp
# 禁用所有配置加载
bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./app.ts " ],
compile : {
// tsconfig.json 和 package.json 默认禁用
autoloadTsconfig : true , // 启用 tsconfig.json 加载
autoloadPackageJson : true , // 启用 package.json 加载
// .env 和 bunfig.toml 默认启用
autoloadDotenv : false , // 禁用 .env 加载
autoloadBunfig : false , // 禁用 bunfig.toml 加载
outfile : " ./myapp " ,
},
});
作为 Bun CLI 使用
通过设置环境变量 BUN_BE_BUN=1,可以让独立可执行文件模拟 bun CLI 自身行为。此时可执行文件会忽略自身打包的入口点,转而暴露 Bun CLI 的所有功能。
For example, consider an executable compiled from this script:
echo " console.log( \" you shouldn't see this \" ); " > such-bun.js
bun build --compile ./such-bun.js
[3ms] bundle 1 modules
[89ms] compile such-bun
通常运行 ./such-bun 会执行该脚本。
# 默认执行打包入口脚本
./such-bun install
但设置 BUN_BE_BUN=1 后,表现如同 bun 命令:
# 通过环境变量让可执行文件行为等同于 `bun` CLI
BUN_BE_BUN = 1 ./such-bun install
bun install v1.2.16-canary.1 (1d1db811)
Checked 63 installs across 64 packages (no changes) [5.00ms]
此功能适合基于 Bun 开发 CLI 工具,既可安装包、打包依赖,又能运行不同或本地文件,无需单独下载或安装 Bun。
全栈可执行文件
Bun 的 --compile 标志可生成包含服务端和客户端代码的独立可执行文件,非常适合全栈应用。当在服务端代码中导入 HTML 文件时,Bun 会自动打包所有前端资源(JavaScript、CSS 等)并嵌入可执行文件。遇到 HTML 导入时,Bun 会启动前端构建流程完成打包。
server.ts
index.html
app.ts
styles.css
import { serve } from " bun " ;
import index from " ./index.html " ;
const server = serve ({
routes : {
" / " : index,
" /api/hello " : { GET : () => Response. json ({ message : " Hello from API " }) },
},
});
console. log ( `Server running at http://localhost: ${ server . port } ` );
构建为单个可执行文件:
bun build --compile ./server.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./server.ts " ],
compile : {
outfile : " ./myapp " ,
},
});
生成的独立二进制包含:
你的服务器代码
Bun 运行时
所有前端资源(HTML、CSS、JavaScript)
服务器用到的所有 npm 包
结果是单个文件,部署无需 Node.js、Bun 或其他依赖。只需运行:
Bun 会自动处理前端资源的 MIME 类型和缓存头。HTML 引入会被替换成 Bun.serve 用来高效服务预打包资源的清单对象。
更多全栈应用构建细节请参见全栈指南 。
Worker
使用独立可执行文件中的 Worker,需要将 Worker 入口也加入构建:
bun build --compile ./index.ts ./my-worker.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./index.ts " , " ./my-worker.ts " ],
compile : {
outfile : " ./myapp " ,
},
});
然后在代码中这样引用 Worker:
index.ts console. log ( " Hello from Bun! " );
// 以下方式均可:
new Worker ( " ./my-worker.ts " );
new Worker ( new URL ( " ./my-worker.ts " , import . meta .url));
new Worker ( new URL ( " ./my-worker.ts " , import . meta .url).href);
多入口点的独立可执行文件会将它们分别打包进可执行文件。
未来可能支持自动检测 new Worker(path) 中静态路径的用法并自动打包,但现在仍需手动在命令行中加入。
如果对相对路径的文件未包括在可执行文件中,启动时会尝试从进程当前工作目录加载(找不到则报错)。
SQLite
使用 bun:sqlite 导入时,支持 bun build --compile。
默认情况下,数据库文件路径相对进程当前工作目录。
index.ts 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
嵌入静态资源及文件
独立可执行文件支持直接将文件嵌入二进制,方便将图片、JSON 配置、模板等资源打包进单文件程序。
机制原理
使用 with { type: "file" } 导入属性 来嵌入文件:
index.ts import icon from " ./icon.png " with { type : " file " };
console. log (icon);
// 开发时为 "./icon.png"
// 编译后为 "$bunfs/icon-a1b2c3d4.png"(内部路径)
此导入返回路径字符串 ,指向嵌入文件。构建时 Bun 会:
读取文件内容
内嵌数据到可执行文件
用内部路径(带 $bunfs/ 前缀)替换导入
你可以通过 Bun.file() 或 Node.js 的 fs API 读取嵌入文件。
用 Bun.file() 读取嵌入文件
Bun.file() 是读取嵌入文件的推荐方式:
index.ts import icon from " ./icon.png " with { type : " file " };
import { file } from " bun " ;
// 以不同方式读取文件内容
const bytes = await file (icon). arrayBuffer (); // ArrayBuffer
const text = await file (icon). text (); // 字符串(文本文件)
const blob = file (icon); // Blob 对象
// 在响应中流式传输文件
export default {
fetch ( req ) {
return new Response ( file (icon), {
headers : { " Content-Type " : " image/png " },
});
},
};
用 Node.js fs 读取嵌入文件
嵌入文件可无缝配合 Node.js 文件系统 API:
index.ts import icon from " ./icon.png " with { type : " file " };
import config from " ./config.json " with { type : " file " };
import { readFileSync, promises as fs } from " node:fs " ;
// 同步读取
const iconBuffer = readFileSync (icon);
// 异步读取
const configData = await fs. readFile (config, " utf-8 " );
const parsed = JSON . parse (configData);
// 文件状态检查
const stats = await fs. stat (icon);
console. log ( `Icon size: ${ stats . size } bytes` );
实践示例
嵌入 JSON 配置
index.ts import configPath from " ./default-config.json " with { type : " file " };
import { file } from " bun " ;
// 加载内置默认配置
const defaultConfig = await file (configPath). json ();
// 尝试加载用户配置,失败则为空对象
const userConfig = await file ( " ./user-config.json " )
. json ()
. catch (() => ({}));
const config = { ... defaultConfig, ... userConfig };
HTTP 服务器中提供静态资源
用 Bun.serve() 的 static 路由高效提供静态文件:
server.ts import favicon from " ./favicon.ico " with { type : " file " };
import logo from " ./logo.png " with { type : " file " };
import styles from " ./styles.css " with { type : " file " };
import { file, serve } from " bun " ;
serve ({
static : {
" /favicon.ico " : file (favicon),
" /logo.png " : file (logo),
" /styles.css " : file (styles),
},
fetch ( req ) {
return new Response ( " Not found " , { status : 404 });
},
});
Bun 会自动处理静态路由的 Content-Type 头和缓存策略。
嵌入模板文件
index.ts import templatePath from " ./email-template.html " with { type : " file " };
import { file } from " bun " ;
async function sendWelcomeEmail ( user : { name : string ; email : string }) {
const template = await file (templatePath). text ();
const html = template. replace ( " {{name}} " , user.name). replace ( " {{email}} " , user.email);
// 发送邮件,使用渲染后的模板...
}
嵌入二进制文件
index.ts import wasmPath from " ./processor.wasm " with { type : " file " };
import fontPath from " ./font.ttf " with { type : " file " };
import { file } from " bun " ;
// 加载 WebAssembly 模块
const wasmBytes = await file (wasmPath). arrayBuffer ();
const wasmModule = await WebAssembly. instantiate (wasmBytes);
// 读取字体二进制数据
const fontData = await file (fontPath). bytes ();
嵌入 SQLite 数据库
若要将 SQLite 数据库嵌入可执行文件,需设置 type: "sqlite" 和 embed: "true":
数据库文件必须已存在于磁盘。然后在代码中导入:
index.ts import myEmbeddedDb from " ./my.db " with { type : " sqlite " , embed : " true " };
console. log (myEmbeddedDb. query ( " select * from users LIMIT 1 " ). get ());
最后编译为独立可执行文件:
bun build --compile ./index.ts --outfile mycli
构建时数据库文件必须存在。embed: "true" 告诉打包器将数据库内容内嵌进可执行文件。常规运行 bun run
时数据库文件仍从磁盘加载。
在编译后的可执行文件中,嵌入的数据库为读写模式,但所有更改会在程序退出时丢失(内存存储)。
嵌入 N-API 插件
可将 .node 文件嵌入可执行文件:
index.ts const addon = require ( " ./addon.node " );
console. log (addon. hello ());
如果使用 @mapbox/node-pre-gyp 等工具,需确保 .node 文件被直接 require,否则不会打包成功。
嵌入目录
使用 bun build --compile 时,可包含目录中的文件:
bun build --compile ./index.ts ./public/ ** / * .png
build.ts import { Glob } from " bun " ;
// 使用 Glob 展开文件列表
const glob = new Glob ( " ./public/**/*.png " );
const pngFiles = Array. from (glob. scanSync ( " . " ));
await Bun. build ({
entrypoints : [ " ./index.ts " , ... pngFiles],
compile : {
outfile : " ./myapp " ,
},
});
然后在代码中引用这些文件:
index.ts import icon from " ./public/assets/icon.png " with { type : " file " };
import { file } from " bun " ;
export default {
fetch ( req ) {
// 嵌入文件可通过 Response 流式传输
return new Response ( file (icon));
},
};
这个方法目前是权宜之计,未来会提供更直接的 API。
列出所有嵌入文件
Bun.embeddedFiles 提供了访问所有嵌入文件的 Blob 对象:
index.ts import " ./icon.png " with { type : " file " };
import " ./data.json " with { type : " file " };
import " ./template.html " with { type : " file " };
import { embeddedFiles } from " bun " ;
// 列出所有嵌入文件
for ( const blob of embeddedFiles) {
console. log ( ` ${ blob . name } - ${ blob . size } bytes` );
}
// 输出示例:
// icon-a1b2c3d4.png - 4096 bytes
// data-e5f6g7h8.json - 256 bytes
// template-i9j0k1l2.html - 1024 bytes
Bun.embeddedFiles 中每个元素是带 name 属性的 Blob:
embeddedFiles : ReadonlyArray < Blob > ;
可用于动态为 static 路由提供所有嵌入资源:
server.ts import " ./public/favicon.ico " with { type : " file " };
import " ./public/logo.png " with { type : " file " };
import " ./public/styles.css " with { type : " file " };
import { embeddedFiles, serve } from " bun " ;
// 根据嵌入文件构造静态路由
const staticRoutes : Record < string , Blob > = {};
for ( const blob of embeddedFiles) {
// 去除文件名中的哈希:"icon-a1b2c3d4.png" -> "icon.png"
const name = blob.name. replace ( / - [ a-f0-9 ] + \. / , " . " );
staticRoutes[ `/ ${ name } ` ] = blob;
}
serve ({
static : staticRoutes,
fetch ( req ) {
return new Response ( " Not found " , { status : 404 });
},
});
Bun.embeddedFiles 不含源码文件(.ts、.js 等)以保护源码。
内容哈希
默认嵌入文件名称带有内容哈希,适合通过 URL/CDN 提供,降低缓存失效。但有时想要保留原名:
禁用内容哈希配置资源命名:
bun build --compile --asset-naming= " [name].[ext] " ./index.ts
build.ts await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
outfile : " ./myapp " ,
},
naming : {
asset : " [name].[ext] " ,
},
});
代码压缩(Minification)
启用代码压缩以减少可执行文件体积:
bun build --compile --minify ./index.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
outfile : " ./myapp " ,
},
minify : true , // 启用全部压缩
});
// 或更细粒度控制:
await Bun. build ({
entrypoints : [ " ./index.ts " ],
compile : {
outfile : " ./myapp " ,
},
minify : {
whitespace : true ,
syntax : true ,
identifiers : true ,
},
});
Bun 使用自身压缩器来减小代码体积。不过总体上 Bun 的二进制仍然偏大,未来还会优化。
Windows 平台特有标志
在 Windows 上编译独立可执行文件时,可以定制生成的 .exe 文件的元数据:
# 自定义图标
bun build --compile --windows-icon=path/to/icon.ico ./app.ts --outfile myapp
# 隐藏控制台窗口(GUI 应用)
bun build --compile --windows-hide-console ./app.ts --outfile myapp
build.ts await Bun. build ({
entrypoints : [ " ./app.ts " ],
compile : {
outfile : " ./myapp " ,
windows : {
icon : " ./path/to/icon.ico " ,
hideConsole : true ,
// 额外的 Windows 元数据:
title : " My Application " ,
publisher : " My Company " ,
version : " 1.0.0 " ,
description : " A standalone Windows application " ,
copyright : " Copyright 2024 " ,
},
},
});
Windows 可用选项说明:
icon - 指定 .ico 图标文件路径
hideConsole - 隐藏后台终端窗口(GUI 应用用)
title - 可执行文件属性中的应用标题
publisher - 发布者名称
version - 版本号字符串
description - 描述信息
copyright - 版权声明
这些标志当前无法用于交叉编译,因为它们依赖 Windows API。
macOS 代码签名
为独立可执行文件进行代码签名以消除 Gatekeeper 警告,使用 codesign 命令:
codesign --deep --force -vvvv --sign " XXXXXXXXXX " ./myapp
推荐附带带有 JIT 权限的 entitlements.plist 文件:
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
<! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
< plist version = " 1.0 " >
< dict >
< key >com.apple.security.cs.allow-jit</ key >
< true />
< key >com.apple.security.cs.allow-unsigned-executable-memory</ key >
< true />
< key >com.apple.security.cs.disable-executable-page-protection</ key >
< true />
< key >com.apple.security.cs.allow-dyld-environment-variables</ key >
< true />
< key >com.apple.security.cs.disable-library-validation</ key >
< true />
</ dict >
</ plist >
使用 --entitlements 标志来支持 JIT 权限:
codesign --deep --force -vvvv --sign " XXXXXXXXXX " --entitlements entitlements.plist ./myapp
签名后验证:
codesign -vvv --verify ./myapp
./myapp: valid on disk
./myapp: satisfies its Designated Requirement
代码签名支持需要 Bun v1.2.4 及以上版本。
代码拆分
独立可执行文件支持代码拆分。结合 --compile 和 --splitting 可生成带有运行时动态加载代码拆分块的可执行文件。
bun build --compile --splitting ./src/entry.ts --outdir ./build
build.ts await Bun. build ({
entrypoints : [ " ./src/entry.ts " ],
compile : true ,
splitting : true ,
outdir : " ./build " ,
});
src/entry.ts
src/lazy.ts
console. log ( " Entrypoint loaded " );
const lazy = await import ( " ./lazy.ts " );
lazy. hello ();
运行编译结果:
输出:
Entrypoint loaded
Lazy module loaded
使用插件
插件支持独立可执行文件,允许你在构建过程中转换文件:
build.ts import type { BunPlugin } from " bun " ;
const envPlugin : BunPlugin = {
name : " env-loader " ,
setup ( build ) {
build. onLoad ({ filter : / \. env \. json $ / }, async args => {
// 将 .env.json 文件转换成已验证的配置对象
const env = await Bun. file (args.path). json ();
return {
contents : `export default ${ JSON . stringify ( env ) } ;` ,
loader : " js " ,
};
});
},
};
await Bun. build ({
entrypoints : [ " ./cli.ts " ],
compile : {
outfile : " ./mycli " ,
},
plugins : [envPlugin],
});
使用场景示例 — 构建时嵌入环境配置:
cli.ts import config from " ./config.env.json " ;
console. log ( `Running in ${ config . environment } mode` );
console. log ( `API endpoint: ${ config . apiUrl } ` );
插件可以完成任意转换:YAML/TOML 编译、SQL 查询内联、生成类型安全 API 客户端或预处理模板。详见插件文档 。
不支持的 CLI 参数
当前 --compile 标志仅支持单入口文件,不支持以下参数:
--outdir — 请使用 outfile,除非搭配 --splitting 使用
--public-path
--target=node
--target=browser(未使用 HTML 入口点 — 关于带 .html 文件的 --compile --target=browser,请参见独立 HTML )
--no-bundle — 总是将所有内容打包进可执行文件
API 参考
Bun.build() 中的 compile 选项支持三种形式:
types interface BuildConfig {
entrypoints : string [];
compile : boolean | Bun . Build . Target | CompileBuildOptions ;
// ... 其他 BuildConfig 选项(minify、sourcemap、define、plugins 等)
}
interface CompileBuildOptions {
target ?: Bun . Build . Target ; // 交叉编译目标
outfile ?: string ; // 输出可执行文件路径
execArgv ?: string []; // 运行时参数(process.execArgv)
autoloadTsconfig ?: boolean ; // 加载 tsconfig.json,默认 false
autoloadPackageJson ?: boolean ; // 加载 package.json,默认 false
autoloadDotenv ?: boolean ; // 加载 .env 文件,默认 true
autoloadBunfig ?: boolean ; // 加载 bunfig.toml,默认 true
windows ?: {
icon ?: string ; // .ico 文件路径
hideConsole ?: boolean ; // 隐藏控制台窗口
title ?: string ; // 应用标题
publisher ?: string ; // 发布者名称
version ?: string ; // 版本字符串
description ?: string ; // 描述
copyright ?: string ; // 版权声明
};
}
用法示例:
// 简单布尔值 - 编译为当前平台,输出文件名为入口名
compile : true
// 目标字符串 - 交叉编译,输出文件名为入口名
compile : " bun-linux-x64 "
// 详尽配置对象 - 指定输出文件和其他参数
compile : {
target : " bun-linux-x64 " ,
outfile : " ./myapp " ,
}
支持的目标
Bun.Build.Target type Target =
| " bun-darwin-x64 "
| " bun-darwin-x64-baseline "
| " bun-darwin-arm64 "
| " bun-linux-x64 "
| " bun-linux-x64-baseline "
| " bun-linux-x64-modern "
| " bun-linux-arm64 "
| " bun-linux-x64-musl "
| " bun-linux-arm64-musl "
| " bun-windows-x64 "
| " bun-windows-x64-baseline "
| " bun-windows-x64-modern "
| " bun-windows-arm64 " ;
完整示例
build.ts import type { BunPlugin } from " bun " ;
const myPlugin : BunPlugin = {
name : " my-plugin " ,
setup ( build ) {
// 插件实现
},
};
const result = await Bun. build ({
entrypoints : [ " ./src/cli.ts " ],
compile : {
target : " bun-linux-x64 " ,
outfile : " ./dist/mycli " ,
execArgv : [ " --smol " ],
autoloadDotenv : false ,
autoloadBunfig : false ,
},
minify : true ,
sourcemap : " linked " ,
bytecode : true ,
define : {
" process.env.NODE_ENV " : JSON . stringify ( " production " ),
VERSION : JSON . stringify ( " 1.0.0 " ),
},
plugins : [myPlugin],
});
if (result.success) {
console. log ( " 构建成功: " , result.outputs[ 0 ].path);
}