Skip to content

配置 Bun 的开发环境可能需要 10-30 分钟,具体取决于你的网络连接和计算机速度。你将需要约 10GB 的可用磁盘空间用于仓库和构建产物。

如果你使用 Windows,请参考 本指南

使用 Nix(替代方案)

提供了一个 Nix flake 作为手动安装依赖的替代方案:

bash
nix develop
# 或者显式使用纯 shell
# nix develop .#pure
export CMAKE_SYSTEM_PROCESSOR=$(uname -m)
bun bd

这在隔离的、可重现的环境中提供所有依赖,无需 sudo 权限。

安装依赖(手动)

使用系统的包管理器安装 Bun 的依赖:

bash
$ brew install automake cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby sccache
bash
$ sudo apt install curl wget lsb-release software-properties-common cargo cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
bash
$ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
bash
$ sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
bash
$ sudo zypper install go cmake ninja automake git icu rustup && rustup toolchain install stable

注意:Zig 编译器会自动安装和更新由构建脚本完成。无需手动安装。

开始之前,你需要已经安装好 Bun 的发布版本,因为我们使用自己的打包器来转译和压缩代码,以及用于代码生成脚本。

bash
$ curl -fsSL https://bun.com/install | bash
bash
$ npm install -g bun
bash
$ brew tap oven-sh/bun
$ brew install bun

可选:安装 sccache

sccache 用于缓存编译产物,显著加快构建速度。它必须安装 S3 支持:

bash
# 对于 macOS
$ brew install sccache

# 对于 Linux。注意你的包管理器中的版本可能没有 S3 支持。
$ cargo install sccache --features=s3

这将安装带有 S3 支持的 sccache。我们的构建脚本会自动检测并使用带有我们共享 S3 缓存的 sccache注意:并非所有版本的 sccache 都编译时带有 S3 支持,因此我们建议通过 cargo 安装它。

sccache 注册 AWS 凭证(仅限核心开发人员)

核心开发人员拥有共享 S3 缓存的写入权限。要启用写入权限,你必须使用 AWS 凭证登录。最简单的方法是使用 aws CLI 并调用 aws configure 提供你的 AWS 安全信息

cmake 脚本应该会自动从环境或 ~/.aws/credentials 文件中检测你的 AWS 凭证。

登录到 `aws` CLI
1. 按照 [官方指南](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 安装 AWS CLI。
2. 登录到你的 AWS 账户控制台。团队成员应该向你提供你的凭证。
3. 点击右上角你的名字 > Security credentials。
4. 滚动到 "Access keys" 并创建新的访问密钥。
5. 在终端中运行 `aws configure` 并在提示时提供访问密钥 ID 和秘密访问密钥。
常见问题
- 要确认缓存正在使用,你可以在构建后立即使用 `sccache --show-stats` 命令。这将显示非常有用的统计信息,包括缓存命中/未命中。
- 如果你配置了多个 AWS 配置文件,请确保在 `AWS_PROFILE` 环境变量中设置了正确的配置文件。
- `sccache` 遵循服务器 - 客户端模型。如果你遇到 `sccache` 拒绝使用 S3 的奇怪问题,即使你已经配置了 AWS 凭证,尝试使用 `sccache --stop-server` 终止任何正在运行的 `sccache` 服务器,然后重新运行构建。

安装 LLVM

Bun 需要 LLVM 19(clang 是 LLVM 的一部分)。这个版本要求是为了匹配 WebKit(预编译),因为版本不匹配会导致运行时内存分配失败。在大多数情况下,你可以通过系统包管理器安装 LLVM:

bash
$ brew install llvm@19
bash
$ # LLVM 有一个自动安装脚本,兼容所有版本的 Ubuntu
$ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 19 all
bash
$ sudo pacman -S llvm clang lld
bash
$ sudo dnf install llvm clang lld-devel
bash
$ sudo zypper install clang19 lld19 llvm19

如果以上解决方案都不适用,你将不得不 手动 安装它。

确保 Clang/LLVM 19 在你的路径中:

bash
$ which clang-19

如果没有,运行此命令手动添加它:

bash
# 如果你使用 fish,使用 fish_add_path
# 如果你使用 zsh,使用 path+="$(brew --prefix llvm@19)/bin"
$ export PATH="$(brew --prefix llvm@19)/bin:$PATH"
bash
# 如果你使用 fish,使用 fish_add_path
$ export PATH="$PATH:/usr/lib/llvm19/bin"

构建 Bun

克隆仓库后,运行以下命令进行构建。这可能需要一段时间,因为它将克隆子模块并构建依赖项。

bash
bun run build

二进制文件将位于 ./build/debug/bun-debug。建议将这个添加到你的 $PATH。要验证构建是否成功,让我们打印开发版本 Bun 的版本号。

bash
$ build/debug/bun-debug --version
x.y.z_debug

VSCode

VSCode 是用于处理 Bun 的推荐 IDE,因为它已经配置好了。打开后,你可以运行 Extensions: Show Recommended Extensions 来安装推荐的 Zig 和 C++ 扩展。ZLS 会自动配置。

如果你使用不同的编辑器,请确保告诉 ZLS 使用自动安装的 Zig 编译器,它位于 ./vendor/zig/zig.exe。文件名是 zig.exe 以便在 Windows 上按预期工作,但它在 macOS/Linux 上仍然有效(只是有一个令人惊讶的文件扩展名)。

我们建议将 ./build/debug 添加到你的 $PATH,这样你就可以在终端中运行 bun-debug

sh
bun-debug

运行调试构建

bd package.json 脚本编译并运行 Bun 的调试版本,仅在构建过程失败时打印输出。

sh
bun bd <args>
bun bd test foo.test.ts
bun bd ./foo.ts

当有 Zig 更改时,Bun 编译调试版本大约需要 2.5 分钟。如果你的开发工作流是 "更改一行代码,保存,重新构建",你会花太多时间等待构建完成。相反:

  • 批量处理你的更改
  • 确保 zls 正在运行增量监视以获取 LSP 错误(如果你使用 VSCode 并安装 Zig 并运行 bun run build 一次下载 Zig,这应该可以正常工作)
  • 更喜欢使用调试器(VSCode 中的 "CodeLLDB")来逐步执行代码。
  • 使用调试日志。BUN_DEBUG_<scope>=1 将为相应的 Output.scoped(.<scope>, .hidden) 日志启用调试日志。你还可以设置 BUN_DEBUG_QUIET_LOGS=1 来禁用所有未显式启用的调试日志。要将调试日志转储到文件中,使用 BUN_DEBUG=<path-to-file>.log。调试日志在发布版本中会被积极地移除。
  • src/js/**.ts 更改几乎可以瞬间重新构建。C++ 更改稍慢一些,但仍比 Zig 代码快得多(Zig 是一个编译单元,C++ 是多个)。

代码生成脚本

Bun 的构建过程中使用了几个代码生成脚本。当对某些文件进行更改时,这些脚本会自动运行。

特别是这些:

  • ./src/codegen/generate-jssink.ts -- 生成 build/debug/codegen/JSSink.cppbuild/debug/codegen/JSSink.h,实现各种用于与 ReadableStream 交互的类。这是内部 FileSinkArrayBufferSink"type": "direct" 流和其他与流相关的代码的工作方式。
  • ./src/codegen/generate-classes.ts -- 生成 build/debug/codegen/ZigGeneratedClasses*,为 Zig 中实现的 JavaScriptCore 类生成 Zig 和 C++ 绑定。在 **/*.classes.ts 文件中,我们定义了各种类、方法、原型、getter/setter 等的接口,代码生成器读取这些接口来生成实现 C++ 中 JavaScript 对象并将其连接到 Zig 的样板代码
  • ./src/codegen/cppbind.ts -- 为标记有 [[ZIG_EXPORT]] 属性的 C++ 函数生成自动 Zig 绑定。
  • ./src/codegen/bundle-modules.ts -- 将内置模块(如 node:fsbun:ffi)打包到我们可以包含在最终二进制文件中的文件中。在开发过程中,这些可以在不重新构建 Zig 的情况下重新加载(你仍然需要运行 bun run build,但之后它会从磁盘重新读取转译的文件)。在发布版本中,这些会嵌入到二进制文件中。
  • ./src/codegen/bundle-functions.ts -- 打包在 JavaScript/TypeScript 中实现的全局可访问函数,如 ReadableStreamWritableStream 以及其他一些函数。这些的使用方式与内置模块类似,但输出更接近 WebKit/Safari 对 Safari 内置函数的处理方式,这样我们可以从 WebKit 复制粘贴实现作为起点。

修改 ESM 模块

某些模块(如 node:fsnode:streambun:sqlitews)是用 JavaScript 实现的。这些位于 src/js/{node,bun,thirdparty} 文件中,并使用 Bun 预打包。

发布构建

要编译 Bun 的发布版本,运行:

bash
bun run build:release

二进制文件将位于 ./build/release/bun./build/release/bun-profile

从拉取请求下载发布构建

为了节省你在本地构建发布版本的时间,我们提供了一种运行拉取请求中发布版本的方法。这对于在合并之前在发布版本中手动测试更改很有用。

要从拉取请求运行发布版本,你可以使用 bun-pr npm 包:

sh
bunx bun-pr <pr-number>
bunx bun-pr <branch-name>
bunx bun-pr "https://github.com/oven-sh/bun/pull/1234566"
bunx bun-pr --asan <pr-number> # 仅限 Linux x64

这将下载拉取请求中的发布版本,并将其作为 bun-${pr-number} 添加到 $PATH 中。然后你可以使用 bun-${pr-number} 运行构建。

sh
bun-1234566 --version

这是通过从链接的拉取请求上的 GitHub Actions 构件下载发布版本来工作的。你可能需要安装 gh CLI 来进行 GitHub 身份验证。

AddressSanitizer

AddressSanitizer 有助于发现内存问题,在 Linux 和 macOS 上的 Bun 调试版本中默认启用。这包括 Zig 代码和所有依赖项。它使 Zig 代码的构建时间大约增加 2 倍,如果这影响了你的工作效率,你可以通过在 cmake/targets/BuildBun.cmake 文件中将 -Denable_asan=$<IF:$<BOOL:${ENABLE_ASAN}>,true,false> 设置为 -Denable_asan=false 来禁用它,但通常我们建议在构建之间批量处理你的更改。

要使用 Address Sanitizer 构建发布版本,运行:

bash
bun run build:release:asan

在 CI 中,我们使用至少一个使用 Address Sanitizer 构建的目标运行测试套件。

在本地构建 WebKit + JSC 调试模式

WebKit 默认不克隆(为了节省时间和磁盘空间)。要在本地克隆和构建 WebKit,运行:

bash
# 将 WebKit 克隆到 ./vendor/WebKit
$ git clone https://github.com/oven-sh/WebKit vendor/WebKit

# 检出 `cmake/tools/SetupWebKit.cmake` 中 `set(WEBKIT_VERSION <commit_hash>)` 指定的提交哈希
$ git -C vendor/WebKit checkout <commit_hash>

# 创建 JSC 的调试版本。这将在 ./vendor/WebKit/WebKitBuild/Debug 中输出构建产物
# 或者,你可以使用 `bun run jsc:build` 进行发布构建
bun run jsc:build:debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h

# 在初次运行 `make jsc-debug` 后,你可以使用以下命令重新构建 JSC:
$ cmake --build vendor/WebKit/WebKitBuild/Debug --target jsc && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h

# 使用本地 JSC 构建 bun
bun run build:local

使用 bun run build:local 将在 ./build/debug-local 目录(而不是 ./build/debug)中构建 Bun,你需要更改几个地方以使用这个新目录:

  • src/js/builtins.d.ts 的第一行
  • .clangd 配置中的 CompilationDatabase 行应该是 CompilationDatabase: build/debug-local
  • build.zig 中,codegen_path 选项应该是 build/debug-local/codegen(而不是 build/debug/codegen
  • .vscode/launch.json 中,许多配置使用 ./build/debug/,根据需要更改它们

注意 WebKit 文件夹(包括构建产物)大小为 8GB+。

如果你使用 JSC 调试版本并使用 VScode,请确保运行 C/C++: Select a Configuration 命令来配置 intellisense 以找到调试头文件。

注意,如果你要更改 我们的 WebKit 分支,你还需要更改 SetupWebKit.cmake 以指向提交哈希。

故障排除

在 Ubuntu 上找不到 'span' 文件

Clang 编译器默认使用 libstdc++ C++ 标准库。libstdc++ 是 GNU 编译器集合(GCC)提供的默认 C++ 标准库实现。虽然 Clang 可以链接到 libc++ 库,但这需要在运行 Clang 时显式提供 -stdlib 标志。

Bun 依赖于 C++20 特性,如 std::span,这些特性在 GCC 11 以下版本中不可用。GCC 10 没有实现所有 C++20 特性。因此,运行 make setup 可能会失败并出现以下错误:

txt
fatal error: 'span' file not found
#include <span>
         ^~~~~~

这个问题可能在初次运行 bun setup 时表现为 Clang 无法编译一个简单的测试程序:

txt
The C++ compiler

  "/usr/bin/clang++-19"

is not able to compile a simple test program.

要修复此错误,我们需要将 GCC 版本更新为 11。为此,我们需要检查发行版的官方仓库中是否有最新版本,或使用提供 GCC 11 包的第三方仓库。以下是一般步骤:

bash
$ sudo apt update
$ sudo apt install gcc-11 g++-11
# 如果上面的命令失败并显示 `Unable to locate package gcc-11`,我们需要添加 APT 仓库
$ sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# 现在再次运行 `apt install`
$ sudo apt install gcc-11 g++-11

现在,我们需要将 GCC 11 设置为默认编译器:

bash
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100

libarchive

如果你在 macOS 上编译 libarchive 时看到错误,运行:

bash
$ brew install pkg-config

macOS library not found for -lSystem

如果你在编译时看到此错误,运行:

bash
$ xcode-select --install

找不到 libatomic.a

Bun 默认静态链接 libatomic,因为并非所有系统都有它。如果你在确实没有静态 libatomic 的发行版上构建,你可以运行以下命令启用动态链接:

bash
bun run build -DUSE_STATIC_LIBATOMIC=OFF

如果以这种方式编译,Bun 的构建版本可能无法在其他系统上运行。

使用 bun-debug

  • 禁用日志:BUN_DEBUG_QUIET_LOGS=1 bun-debug ...(禁用所有调试日志)
  • 为特定的 zig 作用域启用日志:BUN_DEBUG_EventLoop=1 bun-debug ...(允许 std.log.scoped(.EventLoop)
  • Bun 会转译它运行的每个文件,要在调试版本中查看实际执行的源代码,可以在 /tmp/bun-debug-src/...path/to/file 中找到它,例如 /home/bun/index.ts 的转译版本将在 /tmp/bun-debug-src/home/bun/index.ts

Bun学习网由www.bunjs.com.cn整理维护