執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

貢獻

貢獻給 Bun

設定 Bun 的開發環境可能需要 10 到 30 分鐘,具體取決於您的網路連線和計算機速度。您需要大約 10GB 的可用磁碟空間用於儲存儲存庫和建置產物。

如果您使用的是 Windows,請參閱建置 Windows。

使用 Nix(可選方案)

該儲存庫包含一個 Nix flake,可作為手動安裝相依的替代方案:

bash
nix develop
bun bd

nix develop 會在無需 sudo 的情況下,在隔離且可復現的環境中提供所有相依。

安裝相依(手動)

使用系統的套件管理器安裝 Bun 的相依:

macOS
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rustup-init ruby
Ubuntu/Debian
sudo apt install curl wget lsb-release software-properties-common cmake git golang libtool ninja-build pkg-config ruby-full xz-utils
Arch
sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rustup sed unzip ruby
Fedora
sudo dnf install clang23 llvm23 lld23 cmake git golang libtool ninja-build pkg-config ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
openSUSE
sudo zypper install go cmake ninja automake git icu rustup

Bun 使用 Rust 編寫,需要特定的 nightly 工具鏈(已固定在 rust-toolchain.toml 中)。請使用 rustup 安裝 Rust,而不是使用發行版提供的 rust/cargo 軟體包——建置指令碼會使用 rustup 自動安裝並更新已固定的 nightly 工具鏈:

bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

開始之前,請安裝 Bun 的釋出版本:建置過程會使用 Bun 的打包器來轉換和壓縮程式碼,並執行程式碼生成指令碼。

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

可選:安裝 ccache

ccache 會快取編譯產物,從而加快重新建置的速度:

bash
# macOS
brew install ccache

# Ubuntu/Debian
sudo apt install ccache

# Arch
sudo pacman -S ccache

# Fedora
sudo dnf install ccache

# openSUSE
sudo zypper install ccache

如果 ccache 可用,建置指令碼會自動檢測並使用它。使用 ccache --show-stats 檢查快取統計資訊。

安裝 LLVM

Bun 需要 LLVM 23.1.1(clang 是 LLVM 的一部分)。建置系統會強制使用此版本:版本不匹配會導致執行環境記憶體分配失敗。在大多數情況下,您可以通過系統套件管理器安裝 LLVM:

macOS
brew install llvm@23
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 -- 23 all
Arch
sudo pacman -S llvm clang lld
Fedora
sudo dnf install llvm clang lld-devel
openSUSE
sudo zypper install clang23 lld23 llvm23

如果以上方法都不起作用,請手動安裝。

確保 Clang/LLVM 23 位於您的路徑中:

bash
which clang-23

如果沒有,請手動新增:

macOS
# use fish_add_path if you're using fish
# use path+="$(brew --prefix llvm@23)/bin" if you are using zsh
export PATH="$(brew --prefix llvm@23)/bin:$PATH"
Arch
# use fish_add_path if you're using fish
export PATH="$PATH:/usr/lib/llvm23/bin"

建置 Bun

克隆儲存庫後,執行以下命令進行建置。此過程可能需要一段時間:它會下載並建置相依項。

bash
bun run build

二進位制檔案位於 ./build/debug/bun-debug。建議將其新增到 $PATH 中。要驗證建置是否成功,請輸出其版本:

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

VSCode

VSCode 是用於開發 Bun 的推薦 IDE;儲存庫中已包含相應設定。開啟儲存庫後,執行 Extensions: Show Recommended Extensions 以安裝 Rust 和 C++ 的推薦擴充套件。rust-analyzer 會自動識別工作區中的 Cargo.toml,並使用 rust-toolchain.toml 中固定的工具鏈進行分析,因此診斷結果會與建置結果一致。

如果您使用其他編輯器,請將 rust-analyzer(或編輯器的 Rust 外掛)指向儲存庫根目錄——Cargo 工作區和 rust-toolchain.toml 會自動被識別。

推薦將 ./build/debug 新增到您的 $PATH,這樣就可以在終端中直接執行:

shell
bun-debug

執行除錯建置

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

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

完整的除錯建置在 Rust 或 C++ 發生更改時可能需要幾分鐘;cargo 的增量編譯會讓後續僅 Rust 的重建快得多。如果您的開發流程是“改一行、儲存、重建”,您仍然會在等待連結步驟上花費太多時間。相反:

  • 批次進行更改
  • 使用 cargo check -p <crate>(或對整個工作區使用 bun run rust:check)在不連結的情況下對 Rust 更改進行型別檢查。bun run watch 會在每次儲存時執行 cargo check。
  • 確保 rust-analyzer 正在執行,以獲取行內診斷資訊(推薦的 VSCode 擴充套件集會自動完成設定)
  • 優先使用偵錯程式(VSCode 中的“CodeLLDB”)逐步執行程式碼。
  • 使用除錯日誌。BUN_DEBUG_<scope>=1 會為相應的 declare_scope!(<scope>, ...) / scoped_log!(<scope>, ...) 日誌啟用除錯記錄。設定 BUN_DEBUG_QUIET_LOGS=1 可停用所有未明確啟用的除錯日誌。要將除錯日誌轉儲到檔案中,請設定 BUN_DEBUG=<path-to-file>.log。釋出建置會移除除錯日誌。
  • src/js/**/*.ts 的更改幾乎會立即完成重建。單 crate 的 Rust 更改和 C++ 更改都支援增量建置;只有最終連結無法避免。

程式碼生成指令碼

當某些檔案發生變化時,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 -- 為用 Rust 實現的 JavaScriptCore 類生成 Rust 和 C++ 繫結。**/*.classes.ts 檔案定義類、方法、原型以及 getter/setter 的介面;程式碼生成器讀取這些介面,生成用於在 C++ 中實現 JavaScript 物件並將其與 Rust 連線起來的樣板程式碼。
  • ./src/codegen/cppbind.ts -- 掃描標記有匯出屬性的 C++ 繫結,併為它們生成自動的 Rust FFI 包裝器(cpp.rs)。
  • ./src/codegen/bundle-modules.ts -- 將 node:fs、bun:ffi 等內建模組打包到最終二進位制檔案所包含的檔案中。在開發過程中,這些模組可以在不重新建置原生程式碼的情況下重新載入(仍然需要執行 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 的釋出版本,執行:

bash
bun run build:release

二進位制檔案位於 ./build/release/bun 和 ./build/release/bun-profile。

從 Pull Request 下載釋出版本建置

你可以直接執行來自 Pull Request 的釋出版本建置,而無需在本地建置,這對於在合併更改之前手動測試非常有用。

使用 bun-pr npm 包:

shell
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 會從 Pull Request 的 GitHub Actions 建置產物中下載釋出版本建置,並將其以 bun-${pr-number} 的名稱新增到 $PATH,因此你可以直接執行它:

shell
bun-1234566 --version

你可能需要安裝 gh CLI 才能通過 GitHub 身份驗證。

從終端檢視 CI 失敗情況

Bun 的 CI 在 BuildKite 上執行。安裝 BuildKite CLI(brew install buildkite/buildkite/bk),並將 BUILDKITE_API_TOKEN 設定為只讀作用域的 API token。儲存庫包含一個 .bk.yaml,因此 bk 命令預設使用 bun pipeline。

shell
bun run ci:status         # 當前分支最新建置的進度摘要
bun run ci:errors         # 渲染後的測試失敗輸出,標記 [new] 與 [also on main]
bun run ci:logs           # 將每個失敗任務的完整日誌儲存到 ./tmp/ci-<build>/
bun run ci:watch          # 監視直到建置完成
bun run ci:find           # 列印建置編號(可與原始 `bk` 組合使用)

以上所有命令都接受一個目標:#1234(PR 編號)、PR URL、分支名或建置編號。如果不指定,則使用當前 git 分支。

AddressSanitizer

AddressSanitizer 有助於發現記憶體問題,並且在 Linux 和 macOS 上 Bun 的除錯建置中預設啟用。它覆蓋 Rust 程式碼、C++ 繫結以及所有相依項。這會讓建置時間大約增加 2 倍;如果這影響到您的效率,您可以使用 bun run build:debug:noasan 停用它(或者向 scripts/build.ts 傳遞 --asan=off),但通常我們建議您在兩次建置之間批次完成更改。

要使用 AddressSanitizer 建置釋出版本,請執行:

bash
bun run build:asan

CI 會執行測試套件,其中至少有一個目標是使用 AddressSanitizer 建置的。

本地建置 WebKit + JSC 除錯模式

預設不克隆 WebKit(節約時間和空間)。要本地克隆並建置 WebKit:

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

# 檢出 scripts/build/deps/webkit.ts 中 WEBKIT_VERSION 指定的版本
# (可以是提交 SHA 或 autobuild-* 釋出標籤;兩者都支援)
bun sync-webkit-source

# 建置 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 會處理所有事項:設定 JSC、建置 JSC 和建置 Bun。後續執行環境,如果任何 WebKit 原始碼發生更改,JSC 都會增量重建。

  • src/js/builtins.d.ts 第一行

  • .clangd 設定中的 CompilationDatabase 路徑改為 build/debug-local

  • build.zig 中的 codegen_path 改為 build/debug-local/codegen

  • .vscode/launch.json 中相應設定的路徑改為 ./build/debug-local/

  • src/js/builtins.d.ts 第一行

  • .clangd 設定中的 CompilationDatabase 行應為 CompilationDatabase: build/debug-local

  • .vscode/launch.json 中,許多設定使用了 ./build/debug/,請按需修改

WebKit 資料夾(包括建置產物)大小超過 8GB。

如果你在 VSCode 中使用 JSC 除錯版本,請執行 C/C++: Select a Configuration 命令,以便 IntelliSense 找到除錯標頭檔案。

如果你修改了 Bun 的 WebKit fork,還必須修改 scripts/build/deps/webkit.ts 中的 WEBKIT_VERSION,使其指向你的提交雜湊或釋出標籤。

Ubuntu 上出現 'span' 檔案未找到

Clang 預設使用 libstdc++,這是由 GNU Compiler Collection(GCC)提供的 C++ 標準庫實現。Clang 也可以改為連結 libc++,但這需要顯式傳遞 -stdlib 標誌。

Bun 相依 std::span 等 C++20 特性,而這些特性在低於 11 的 GCC 版本中不可用。因此,執行 bun run build 可能會失敗,並出現以下錯誤:

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

首次執行 bun run build 時也可能出現此問題,此時 Clang 無法編譯一個簡單的程式:

Text
The C++ compiler

  "/usr/bin/clang++-23"

is not able to compile a simple test program.

要修復此錯誤,請將 GCC 更新到 11 版本。你的發行版官方儲存庫中可能已提供該版本;否則,請新增提供 GCC 11 軟體包的第三方儲存庫:

bash
sudo apt update
sudo apt install gcc-11 g++-11
# 如果報錯找不到包,需新增 APT 儲存庫
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# 再試安裝
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 --static-libatomic=off

但這樣建置的 Bun 可能無法在其他系統執行。

使用 bun-debug

  • 停用日誌:BUN_DEBUG_QUIET_LOGS=1 bun-debug ...(停用所有除錯日誌)
  • 為特定作用域啟用日誌:BUN_DEBUG_EventLoop=1 bun-debug ...(啟用 scoped_log!(EventLoop, ...) 輸出)
  • Bun 會轉譯執行的每個檔案。要在除錯建置中檢視實際執行的原始碼,請在 /tmp/bun-debug-src/...path/to/file 中查詢。例如,/home/bun/index.ts 的轉譯版本位於 /tmp/bun-debug-src/home/bun/index.ts

貢獻文件

文件是 Bun 儲存庫 docs/ 目錄中的 MDX 檔案。bun.com/docs 根據這些檔案建置。

文風

文件頁面介紹 Bun 的功能以及你可以用它做什麼。寫作時應讓剛接觸 Bun 的開發者讀一遍頁面後就能採取行動。以下指南改編自 Next.js 文件貢獻指南:

  • 寫簡短的句子,每句話只表達一個要點。如果一句話需要多個逗號或括號,請拆分句子或改為列表。
  • 使用簡單的詞語:用“使用”代替“利用”,用“為了”代替“以便”。刪去“請注意”和“請”等填充語。
  • 使用主動語態並指出動作主體:“Bun 讀取 bunfig.toml”,而不是“bunfig.toml 被讀取”。以“是”和“被”構成的句子通常是被動語態。
  • 用現在時描述當前行為:“Bun 安裝該軟體包”,而不是“Bun 將安裝該軟體包”。
  • 如果“這”或“它”可能指代多個物件,請明確說出主體:“--isolate 是 Jest 的預設行為”,而不是“這是 Jest 的預設行為”。
  • 用“你”稱呼讀者,並讓 Bun(或具體工具)作為另一個動作主體:“Bun 快取壓縮包”,而不是“我們快取壓縮包”或“讓我們快取壓縮包”。
  • 不要使用“容易”“簡單”“只是”和“快速”。當任務很容易時,這些詞沒有意義;當任務並不容易時,它們會讓讀者氣餒。請明確說明具體特性:“一條命令”“無需設定”。
  • 說明應該做什麼,而不是應該避免什麼:“使用 port: 0,讓作業系統選擇一個可用埠”,而不是“不要將埠寫死”。直接說明限制;限制是事實,不是對讀者的警告。
  • 使用性別中立的表達:“開發者”“使用者”“他們”。
  • 讓連結文本明確指出其目標:“請參閱 bun install”,而不是“請參閱此處”。
  • 釋出前執行每個程式碼範例,並根據 main 上的實現檢查選項名稱和預設值。