Bun

貢獻

為 Bun 配置開發環境可能需要 10-30 分鐘,具體取決於您的網路連線和計算機速度。您需要大約 10GB 的空閒磁碟空間用於儲存倉庫和構建工件。

如果您使用 Windows,請參閱本指南

使用 Nix(替代方案)

Nix flake 作為手動依賴安裝的替代方案提供

nix develop
# or explicitly use the pure shell
# nix develop .#pure
export CMAKE_SYSTEM_PROCESSOR=$(uname -m)
bun bd

這將在隔離的、可重現的環境中提供所有依賴項,而無需 sudo 許可權。

安裝依賴項(手動)

使用您系統的包管理器安裝 Bun 的依賴項

macOS
Ubuntu/Debian
Arch
Fedora
openSUSE
macOS
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby
Ubuntu/Debian
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
Arch
sudo pacman -S base-devel ccache cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
Fedora
sudo dnf install cargo clang19 llvm19 lld19 ccache cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
openSUSE
sudo zypper install go cmake ninja automake git icu rustup && rustup toolchain install stable

注意:Zig 編譯器由構建指令碼自動安裝和更新。無需手動安裝。

在開始之前,您需要已經安裝了 Bun 的釋出版本,因為我們使用我們的打包器來轉譯和縮小我們的程式碼,以及用於程式碼生成指令碼。

原生
npm
Homebrew
原生
curl -fsSL https://bun.nodejs.com.tw/install | bash
npm
npm install -g bun
Homebrew
brew tap oven-sh/bun
brew install bun

安裝 LLVM

Bun 需要 LLVM 19(clang 是 LLVM 的一部分)。此版本要求是為了與 WebKit(預編譯)匹配,因為版本不匹配會導致執行時記憶體分配失敗。在大多數情況下,您可以透過系統包管理器安裝 LLVM

macOS
Ubuntu/Debian
Arch
Fedora
openSUSE
macOS
brew install llvm@19
Ubuntu/Debian
# 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 -- 19 all
Arch
sudo pacman -S llvm clang lld
Fedora
sudo dnf install llvm clang lld-devel
openSUSE
sudo zypper install clang19 lld19 llvm19

如果以上解決方案都不適用,您將需要手動安裝

確保 Clang/LLVM 19 在您的路徑中

which clang-19

如果沒有,執行此命令手動新增

macOS
Arch
macOS
# use fish_add_path if you're using fish
# use path+="$(brew --prefix llvm@19)/bin" if you are using zsh
export PATH="$(brew --prefix llvm@19)/bin:$PATH"
Arch
# use fish_add_path if you're using fish
export PATH="$PATH:/usr/lib/llvm19/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

執行除錯版本

bd package.json 指令碼編譯並執行 Bun 的除錯版本,僅在構建過程失敗時列印輸出。

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_=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 對其內建函式的處理方式,以便我們可以將 WebKit 中的實現複製貼上作為起點。

修改 ESM 模組

某些模組,如 node:fsnode:streambun:sqlitews,是用 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"
bunx bun-pr --asan <pr-number> # Linux x64 only

這將從拉取請求下載釋出版本,並將其作為 bun-${pr-number} 新增到 $PATH。然後您可以使用 bun-${pr-number} 執行構建。

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 構建釋出版本,請執行

bun run build:release:asan

在 CI 中,我們至少使用一個帶有 Address Sanitizer 構建的目標來執行我們的測試套件。

本地構建 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 `bun run jsc:build` for a release build
bun run jsc:build:debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h

# After an initial run of `make jsc-debug`, you can rebuild JSC with:
cmake --build vendor/WebKit/WebKitBuild/Debug --target jsc && 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++: 選擇配置 命令來配置智慧感知以查詢除錯標頭檔案。

請注意,如果您更改了我們的 WebKit fork,您還需要更改 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>
         ^~~~~~

當 Clang 無法編譯一個簡單程式時,在最初執行 bun setup 時可能會出現此問題

The C++ compiler

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

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