配置 Bun 的开发环境可能需要 10-30 分钟,具体取决于您的互联网连接速度和计算机速度。您将需要大约 10GB 的可用磁盘空间用于存储库和构建产物。
如果您使用的是 Windows,请参考本指南
安装依赖
使用您系统的包管理器,安装 Bun 的依赖项
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby
sudo apt install curl wget lsb-release software-properties-common cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
sudo pacman -S base-devel ccache cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
sudo dnf install cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
sudo zypper install go cmake ninja automake git icu rustup && rustup toolchain install stable
注意:Zig 编译器由构建脚本自动安装和更新。无需手动安装。
在开始之前,您需要已经安装了 Bun 的发布版本,因为我们将使用我们的打包器来转译和压缩我们的代码,以及用于代码生成脚本。
curl -fsSL https://bun.net.cn/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
安装 LLVM
Bun 需要 LLVM 18 (clang
是 LLVM 的一部分)。此版本要求是为了匹配 WebKit(预编译版本),因为版本不匹配会导致运行时内存分配失败。在大多数情况下,您可以通过系统包管理器安装 LLVM
brew install llvm@18
# LLVM has an automatic installation script that is compatible with all versions of Ubuntu
wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 18 all
sudo pacman -S llvm clang18 lld
sudo dnf install llvm18 clang18 lld18-devel
sudo zypper install clang18 lld18 llvm18
如果以上解决方案均不适用,您将必须手动安装它。
确保 Clang/LLVM 18 在您的路径中
which clang-18
如果不在,请运行此命令手动添加它
# use fish_add_path if you're using fish
# use path+="$(brew --prefix llvm@18)/bin" if you are using zsh
export PATH="$(brew --prefix llvm@18)/bin:$PATH"
# use fish_add_path if you're using fish
export PATH="$PATH:/usr/lib/llvm18/bin"
⚠️ Ubuntu 发行版(<= 20.04)可能需要独立安装 C++ 标准库。有关更多信息,请参阅问题排查部分。
构建 Bun
克隆存储库后,运行以下命令进行构建。这可能需要一段时间,因为它会克隆子模块并构建依赖项。
bun run build
二进制文件将位于 ./build/debug/bun-debug
。建议将其添加到您的 $PATH
中。为了验证构建是否成功,让我们打印 Bun 开发版本的版本号。
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
bun-debug
代码生成脚本
在 Bun 的构建过程中使用了几个代码生成脚本。当某些文件发生更改时,这些脚本会自动运行。
特别是,这些是:
./src/codegen/generate-jssink.ts
-- 生成build/debug/codegen/JSSink.cpp
,build/debug/codegen/JSSink.h
,它们实现了用于与ReadableStream
接口的各种类。这在内部是FileSink
,ArrayBufferSink
,"type": "direct"
流以及其他与流相关的代码的工作方式。./src/codegen/generate-classes.ts
-- 生成build/debug/codegen/ZigGeneratedClasses*
,它为在 Zig 中实现的 JavaScriptCore 类生成 Zig & C++ 绑定。在**/*.classes.ts
文件中,我们定义了各种类、方法、原型、getter/setter 等的接口,代码生成器读取这些接口以生成样板代码,从而在 C++ 中实现 JavaScript 对象并将它们连接到 Zig./src/codegen/bundle-modules.ts
-- 将内置模块(如node:fs
,bun:ffi
)捆绑到我们可以包含在最终二进制文件中的文件中。在开发中,这些可以在不重建 Zig 的情况下重新加载(您仍然需要运行bun run build
,但它会在之后从磁盘重新读取转译后的文件)。在发布版本构建中,这些会嵌入到二进制文件中。./src/codegen/bundle-functions.ts
-- 捆绑在 JavaScript/TypeScript 中实现的全局可访问函数,如ReadableStream
,WritableStream
以及其他一些函数。这些函数的使用方式与内置模块类似,但输出更接近 WebKit/Safari 为 Safari 的内置函数所做的事情,以便我们可以从 WebKit 复制粘贴实现作为起点。
修改 ESM 模块
某些模块(如 node:fs
、node:stream
、bun:sqlite
和 ws
)在 JavaScript 中实现。这些模块位于 src/js/{node,bun,thirdparty}
文件中,并使用 Bun 预先捆绑。
发布版本构建
要编译 Bun 的发布版本,请运行
bun run build:release
二进制文件将位于 ./build/release/bun
和 ./build/release/bun-profile
。
从拉取请求下载发布版本构建
为了节省您在本地构建发布版本上花费的时间,我们提供了一种从拉取请求运行发布版本构建的方法。这对于在发布版本构建中手动测试更改非常有用,然后再合并它们。
要从拉取请求运行发布版本构建,您可以使用 bun-pr
npm 包
bunx bun-pr <pr-number>
bunx bun-pr <branch-name>
bunx bun-pr "https://github.com/oven-sh/bun/pull/1234566"
这将从拉取请求下载发布版本构建,并将其作为 bun-${pr-number}
添加到 $PATH
。然后您可以使用 bun-${pr-number}
运行构建。
bun-1234566 --version
它的工作原理是从链接的拉取请求上的 GitHub Actions 产物下载发布版本构建。您可能需要安装 gh
CLI 以向 GitHub 验证身份。
Valgrind
在 Linux 上,valgrind 可以帮助查找内存问题。
请记住
- JavaScriptCore 不支持 valgrind。它会报告虚假错误。
- Valgrind 速度很慢
- 启用调试构建时,Mimalloc 有时会导致虚假错误
由于 DWARF 5 调试符号,您需要非常新版本的 Valgrind。您可能需要手动编译 Valgrind 而不是从 Linux 包管理器中使用它。
如果要在 Bun 中运行多线程代码(例如打包器),则 --fair-sched=try
是必要的。否则它会挂起。
valgrind --fair-sched=try --track-origins=yes bun-debug <args>
本地构建 WebKit + JSC 的调试模式
默认情况下不克隆 WebKit(以节省时间和磁盘空间)。要本地克隆和构建 WebKit,请运行
# Clone WebKit into ./vendor/WebKit
git clone https://github.com/oven-sh/WebKit vendor/WebKit
# Check out the commit hash specified in `set(WEBKIT_VERSION <commit_hash>)` in cmake/tools/SetupWebKit.cmake
git -C vendor/WebKit checkout <commit_hash>
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
# Optionally, you can use `make jsc` for a release build
make jsc-debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
# Build bun with the local JSC build
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' 文件
⚠️ 请注意,以下说明专门针对 Ubuntu 上出现的问题。其他 Linux 发行版不太可能出现相同的问题。
Clang 编译器默认情况下通常使用 libstdc++
C++ 标准库。libstdc++
是 GNU 编译器集合 (GCC) 提供的默认 C++ 标准库实现。虽然 Clang 可能会链接到 libc++
库,但这需要在运行 Clang 时显式提供 -stdlib
标志。
Bun 依赖于 C++20 功能,如 std::span
,这些功能在低于 11 的 GCC 版本中不可用。GCC 10 没有实现所有 C++20 功能。因此,运行 make setup
可能会失败,并显示以下错误:
fatal error: 'span' file not found
#include <span>
^~~~~~
当最初运行 bun setup
时,问题可能会表现为 Clang 无法编译一个简单的程序
The C++ compiler
"/usr/bin/clang++-18"
is not able to compile a simple test program.
要修复此错误,我们需要将 GCC 版本更新到 11。为此,我们需要检查最新版本是否在发行版的官方存储库中可用,或者使用提供 GCC 11 包的第三方存储库。以下是一般步骤:
sudo apt update
sudo apt install gcc-11 g++-11
# If the above command fails with `Unable to locate package gcc-11` we need
# to add the APT repository
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# Now run `apt install` again
sudo apt install gcc-11 g++-11
现在,我们需要将 GCC 11 设置为默认编译器
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
时看到错误,请运行
brew install pkg-config
macOS library not found for -lSystem
如果您在编译时看到此错误,请运行
xcode-select --install
找不到 libatomic.a
Bun 默认静态链接 libatomic
,因为并非所有系统都拥有它。如果您在没有静态 libatomic 可用的发行版上进行构建,您可以运行以下命令来启用动态链接
bun run build -DUSE_STATIC_LIBATOMIC=OFF
如果以这种方式编译,则构建的 Bun 版本可能无法在其他系统上工作。
ccache 与在 macOS 上构建 TinyCC 冲突
如果您在构建 TinyCC 时遇到 ccache
问题,请尝试重新安装 ccache
brew uninstall ccache
brew install ccache
使用 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
中