Bun

貢獻

設定 Bun 的開發環境可能需要 10-30 分鐘,取決於您的網路連線速度和電腦速度。您將需要約 10GB 的可用磁碟空間來存放儲存庫和建置產物。

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

安裝相依性

使用您系統的套件管理器,安裝 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 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 的發布版本,因為我們使用我們的 bundler 來轉譯和最小化我們的程式碼,以及用於程式碼產生腳本。

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

安裝 LLVM

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

macOS
Ubuntu/Debian
Arch
Fedora
openSUSE
macOS
brew install llvm@18
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 -- 18 all
Arch
sudo pacman -S llvm clang18 lld
Fedora
sudo dnf install llvm18 clang18 lld18-devel
openSUSE
sudo zypper install clang18 lld18 llvm18

如果以上解決方案都不適用,您將必須手動安裝它。

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

which clang-18

如果沒有,請執行此命令手動添加它

macOS
Arch
macOS
# 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"
Arch
# 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 介接的各種類別。這是在內部 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/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 中運行多線程程式碼 (例如 bundler),則 --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 目錄中建置 Bun (而不是 ./build/debug),您必須更改幾個地方才能使用這個新目錄

  • src/js/builtins.d.ts 中的第一行
  • .clangd config 中的 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 以指向提交雜湊。

疑難排解

'span' 檔案在 Ubuntu 上找不到

⚠️ 請注意,以下說明僅針對 Ubuntu 上發生的問題。相同的問題不太可能在其他 Linux 發行版上發生。

Clang 編譯器通常預設使用 libstdc++ C++ 標準函式庫。libstdc++ 是 GNU Compiler Collection (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