Bun

單一檔案可執行檔

Bun 的打包器實作了一個 --compile 旗標,用於從 TypeScript 或 JavaScript 檔案產生一個獨立的二進位檔。

bash
cli.ts
bun build ./cli.ts --compile --outfile mycli
cli.ts
console.log("Hello world!");

這會將 cli.ts 打包成一個可直接執行的可執行檔

$ ./mycli
Hello world!

所有匯入的檔案和套件都會打包到可執行檔中,連同 Bun 執行時期的副本。所有內建的 Bun 和 Node.js API 都受到支援。

跨平台編譯

--target 旗標可讓您為不同於執行 bun build 的機器作業系統、架構或 Bun 版本編譯您的獨立可執行檔。

為 Linux x64 (大多數伺服器) 建置

bun build --compile --target=bun-linux-x64 ./index.ts --outfile myapp

# To support CPUs from before 2013, use the baseline version (nehalem)
bun build --compile --target=bun-linux-x64-baseline ./index.ts --outfile myapp

# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
# modern is faster, but baseline is more compatible.
bun build --compile --target=bun-linux-x64-modern ./index.ts --outfile myapp

為 Linux ARM64 (例如 Graviton 或 Raspberry Pi) 建置

# Note: the default architecture is x64 if no architecture is specified.
bun build --compile --target=bun-linux-arm64 ./index.ts --outfile myapp

為 Windows x64 建置

bun build --compile --target=bun-windows-x64 ./path/to/my/app.ts --outfile myapp

# To support CPUs from before 2013, use the baseline version (nehalem)
bun build --compile --target=bun-windows-x64-baseline ./path/to/my/app.ts --outfile myapp

# To explicitly only support CPUs from 2013 and later, use the modern version (haswell)
bun build --compile --target=bun-windows-x64-modern ./path/to/my/app.ts --outfile myapp

# note: if no .exe extension is provided, Bun will automatically add it for Windows executables

為 macOS arm64 建置

bun build --compile --target=bun-darwin-arm64 ./path/to/my/app.ts --outfile myapp

針對 macOS x64 進行建置

bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp

支援的目標

只要以 - 分隔,--target 旗標的順序並不重要。

--target作業系統架構現代基準
bun-linux-x64Linuxx64
bun-linux-arm64Linuxarm64不適用
bun-windows-x64Windowsx64
bun-windows-arm64Windowsarm64
bun-darwin-x64macOSx64
bun-darwin-arm64macOSarm64不適用

在 x64 平台上,Bun 使用需要支援 AVX2 指令的現代 CPU 的 SIMD 最佳化。Bun 的 -baseline 建置適用於不支援這些最佳化的舊式 CPU。通常,當您安裝 Bun 時,我們會自動偵測要使用哪個版本,但由於您可能不知道目標 CPU,因此在跨編譯時可能會比較困難。您通常不必擔心 Darwin x64,但這與 Windows x64 和 Linux x64 有關。如果您或您的使用者看到 "Illegal instruction" 錯誤,您可能需要使用基準版本。

部署到生產環境

編譯的可執行檔可減少記憶體使用量,並改善 Bun 的啟動時間。

通常,Bun 會在 importrequire 時讀取並轉譯 JavaScript 和 TypeScript 檔案。這是讓 Bun「正常運作」的部分原因,但這並非免費。從磁碟讀取檔案、解析檔案路徑、剖析、轉譯和列印原始碼需要時間和記憶體。

使用編譯的可執行檔,您可以將這些成本從執行時間轉移到建置時間。

在部署到生產環境時,我們建議您執行下列事項

bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp

這些旗標的作用是什麼?

--minify 參數會最佳化轉譯輸出程式碼的大小。如果您有一個大型應用程式,這可以節省數 MB 的空間。對於較小的應用程式,它可能仍會稍微改善啟動時間。

--sourcemap 參數會內嵌使用 zstd 壓縮的原始碼對應,以便錯誤和堆疊追蹤指向其原始位置,而不是轉譯位置。當發生錯誤時,Bun 會自動解壓縮和解析原始碼對應。

SQLite

您可以使用 bun:sqlite 匯入與 bun build --compile

預設情況下,資料庫會相對於程序的目前工作目錄解析。

import db from "./my.db" with { type: "sqlite" };

console.log(db.query("select * from users LIMIT 1").get());

這表示如果可執行檔位於 /usr/bin/hello,使用者的終端機位於 /home/me/Desktop,它會尋找 /home/me/Desktop/my.db

$ cd /home/me/Desktop
$ ./hello

嵌入資源和檔案

獨立可執行檔支援嵌入檔案。

若要使用 bun build --compile 將檔案嵌入可執行檔中,請在程式碼中匯入檔案

// this becomes an internal file path
import icon from "./icon.png" with { type: "file" };
import { file } from "bun";

export default {
  fetch(req) {
    // Embedded files can be streamed from Response objects
    return new Response(file(icon));
  },
};

可以使用 Bun.file 的函式或 Node.js 的 fs.readFile 函式(在 "node:fs" 中)來讀取嵌入的檔案。

例如,若要讀取嵌入檔案的內容

import icon from "./icon.png" with { type: "file" };
import { file } from "bun";

const bytes = await file(icon).arrayBuffer();

嵌入 SQLite 資料庫

如果您的應用程式想要嵌入 SQLite 資料庫,請在匯入屬性中設定 type: "sqlite",並將 embed 屬性設定為 "true"

import myEmbeddedDb from "./my.db" with { type: "sqlite", embed: "true" };

console.log(myEmbeddedDb.query("select * from users LIMIT 1").get());

此資料庫為讀寫,但當可執行檔結束時,所有變更都會遺失(因為它儲存在記憶體中)。

嵌入 N-API 外掛程式

從 Bun v1.0.23 開始,您可以將 .node 檔案嵌入可執行檔中。

const addon = require("./addon.node");

console.log(addon.hello());

很遺憾的是,如果您使用 @mapbox/node-pre-gyp 或其他類似工具,您需要確保直接需要 .node 檔案,否則它將無法正確組合。

縮小

若要稍微縮小可執行檔的大小,請將 --minify 傳遞給 bun build --compile。這會使用 Bun 的縮小器來縮小程式碼大小。不過,整體而言,Bun 的二進位檔案仍然太大,我們需要讓它變小。

不支援的 CLI 參數

目前,--compile 旗標一次只能接受一個進入點,並且不支援下列旗標

  • --outdir — 改用 outfile
  • --splitting
  • --public-path
  • --target=node--target=browser
  • --format - 始終輸出二進位可執行檔。在內部,它幾乎是 esm。
  • --no-bundle - 我們總是將所有內容打包到可執行檔中。