Bun 1.0 終於釋出了。
Bun 是一個快速、一體化的工具集,用於從單個檔案到完整的應用程式執行、構建、測試和除錯 JavaScript 和 TypeScript。今天,Bun 已經穩定並且可以投入生產使用。
安裝 Bun
curl -fsSL https://bun.nodejs.com.tw/install | bashnpm install -g bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bun升級 Bun
bun upgradeBun 是一個一體化工具集
我們熱愛 JavaScript。它成熟、發展迅速,並且擁有一個充滿活力和熱情的開發者社群。這太棒了。
然而,自 Node.js 問世 14 年以來,一層層工具堆疊在了一起。就像任何一個沒有集中規劃而發展和演變的系統一樣,JavaScript 工具也變得緩慢而複雜。
Bun 存在的理由
Bun 的目標很簡單:在不拋棄 JavaScript 的所有優點的前提下,消除緩慢和複雜。您喜歡的庫和框架應該仍然可用,並且您不必忘記您熟悉的約定。
但是,您確實需要忘記 Bun 使之不再需要的許多工具
Node.js — Bun 是 Node.js 的即插即用替代品,因此您不需要
nodenpx—bunx快 5 倍dotenv,cross-env— Bun 預設讀取.env檔案nodemon,pm2— 內建監視模式ws— 內建 WebSocket 伺服器node-fetch,isomorphic-fetch— 內建fetch
轉譯器 — Bun 可以執行 .js, .ts, .cjs, .mjs, .jsx 和 .tsx 檔案,可以替代
tsc— (但您可以保留它用於型別檢查!)babel,.babelrc,@babel/preset-*ts-node,ts-node-esmtsx
打包器 — Bun 是一個具有一流效能和 esbuild 相容外掛 API 的 JavaScript 打包器,因此您不需要
esbuildwebpackparcel,.parcelrcrollup,rollup.config.js
包管理器 — Bun 是一個相容 npm 的包管理器,具有熟悉的命令。它像其他包管理器一樣讀取您的 package.json 並寫入 node_modules,因此您可以替換
npm,.npmrc,package-lock.jsonyarn,yarn.lockpnpm,pnpm.lock,pnpm-workspace.yamllerna
測試庫 — Bun 是一個 Jest 相容的測試執行器,支援快照測試、模擬和程式碼覆蓋率,因此您不再需要
jest,jest.config.jsts-jest,@swc/jest,babel-jestjest-extendedvitest,vitest.config.ts
雖然這些工具本身都很好(大部分),但將它們組合在一起使用最終會產生脆弱性和緩慢的開發體驗。它們執行了大量冗餘工作;當您執行 jest 時,您的程式碼將被各種工具解析 3 次以上!並且將所有內容粘合在一起所需的膠帶、外掛和介面卡最終都會磨損。
Bun 是一個單一的整合工具集,可以避免這些整合問題。此工具集中的每個工具都提供了最好的一流開發體驗,從效能到 API 設計。
Bun 是一個 JavaScript 執行時
Bun 是一個快速的 JavaScript 執行時。它的目標是讓軟體構建體驗更快、更少令人沮喪、更有趣。
Node.js 相容性
Bun 是 Node.js 的即插即用替代品。這意味著現有的 Node.js 應用程式和 npm 包在 Bun 中可以直接工作。Bun 內建支援 Node API,包括
- 內建模組,如
fs、path和net, - 全域性變數,如
__dirname和process, - 以及 Node.js 模組解析演算法。(例如
node_modules)
雖然與 Node.js 的完美相容是不可能的——特別是 node:v8 ——但 Bun 可以在野外執行幾乎任何 Node.js 應用程式。
Bun 是針對 npm 上最受歡迎的 Node.js 包的測試套件進行測試的。Express、Koa 和 Hono 等伺服器框架可以直接執行。使用最受歡迎的全棧框架構建的應用程式也是如此。總的來說,這些庫和框架觸及了 Node.js API 表面上所有重要的部分。
注意 — 有關 Node.js 相容性的詳細 breakdown,請檢視:bun.sh/nodejs。
速度
Bun 速度很快,啟動速度比 Node.js 快 4 倍(連結)。當執行 TypeScript 檔案時,這種差異只會更加明顯,因為 Node.js 在執行之前需要進行轉譯。
與使用 Google V8 引擎構建的 Node.js 和其他執行時不同,Bun 使用 Apple 的WebKit 引擎構建。WebKit 是為 Safari 提供動力的引擎,並且每天被數十億裝置使用。它速度快、效率高,並且經過了幾十年的實戰檢驗。
TypeScript 和 JSX 支援
Bun 有一個內置於執行時的 JavaScript 轉譯器。這意味著您可以執行 JavaScript、TypeScript,甚至 JSX/TSX 檔案,無需任何依賴。
bun index.tsbun index.jsxbun index.tsxESM 和 CommonJS 相容性
從 CommonJS 到 ES 模組的過渡緩慢而充滿挑戰。在引入 ESM 後,Node.js 花了 5 年時間才無需 --experimental-modules 標誌即可支援它。無論如何,生態系統仍然充斥著 CommonJS。
Bun 始終支援這兩種模組系統。無需擔心副檔名、.js 與 .cjs 或 .mjs,或在 package.json 中包含 "type": "module"。
您甚至可以在同一個檔案中使用 import 和 require()。它就是這樣工作。
import lodash from "lodash";
const _ = require("underscore");
Web API
Bun 內建支援瀏覽器中可用的 Web 標準 API,例如 fetch、Request、Response、WebSocket 和 ReadableStream。
const response = await fetch("https://example.com/");
const text = await response.text();
您不再需要安裝 node-fetch 和 ws 等包。Bun 的內建 Web API 是用原生程式碼實現的,並且比第三方替代品更快、更可靠。
熱過載
Bun 使開發者能夠更輕鬆地提高工作效率。您可以使用 --hot 執行 Bun 來啟用熱過載,它會在檔案更改時重新載入您的應用程式。
bun --hot server.ts與 nodemon 等工具硬重啟整個程序不同,Bun 在不終止舊程序的情況下重新載入程式碼。這意味著 HTTP 和 WebSocket 連線不會斷開,狀態也不會丟失。

外掛
Bun 被設計為高度可定製。
您可以定義外掛來攔截匯入並執行自定義載入邏輯。外掛可以為其他檔案型別新增支援,例如 .yaml 或 .png。該外掛 API 受到 esbuild 的啟發,這意味著大多數 esbuild 外掛在 Bun 中都可以正常工作。
import { plugin } from "bun";
plugin({
name: "YAML",
async setup(build) {
const { load } = await import("js-yaml");
const { readFileSync } = await import("fs");
build.onLoad({ filter: /\.(yaml|yml)$/ }, (args) => {
const text = readFileSync(args.path, "utf8");
const exports = load(text) as Record<string, any>;
return { exports, loader: "object" };
});
},
});
Bun API
Bun 提供了高度最佳化的標準庫 API,用於您作為開發人員最需要的功能。
與 Node.js API(為向後相容性而存在)不同,這些Bun 原生 API 的設計旨在快速易用。
Bun.file()
使用 Bun.file() 來惰性載入特定路徑的 File。
const file = Bun.file("package.json");
const contents = await file.text();
它返回一個 BunFile,它擴充套件了 Web 標準的File。檔案內容可以以各種格式惰性載入。
const file = Bun.file("package.json");
await file.text(); // string
await file.arrayBuffer(); // ArrayBuffer
await file.blob(); // Blob
await file.json(); // {...}
Bun 讀取檔案的速度比 Node.js 快 10 倍(連結)。
Bun.write()
使用 Bun.write() 是一個單一、靈活的 API,用於將幾乎任何內容寫入磁碟——字串、二進位制資料、Blobs,甚至是一個 Response 物件。
await Bun.write("index.html", "<html/>");
await Bun.write("index.html", Buffer.from("<html/>"));
await Bun.write("index.html", Bun.file("home.html"));
await Bun.write("index.html", await fetch("https://example.com/"));
Bun 寫入檔案的速度比 Node.js 快 3 倍(連結)。
Bun.serve()
使用 Bun.serve() 來啟動 HTTP 伺服器、WebSocket 伺服器或兩者。它基於熟悉的 Web 標準 API,如 Request 和 Response。
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
});
Bun 每秒服務的請求數是 Node.js 的 4 倍(連結)。
您還可以使用 tls 選項配置 TLS。
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
tls: {
key: Bun.file("/path/to/key.pem"),
cert: Bun.file("/path/to/cert.pem"),
}
});要支援 WebSocket 和 HTTP,只需在 websocket 中定義一個事件處理程式。與 Node.js 相比,Node.js 不提供內建的 WebSocket API,並且需要第三方依賴項(如 ws)。
Bun.serve({
fetch() { ... },
websocket: {
open(ws) { ... },
message(ws, data) { ... },
close(ws, code, reason) { ... },
},
});
Bun 每秒服務的訊息數是 Node.js 上的 ws 的 5 倍(連結)。
bun:sqlite
Bun 內建支援 SQLite。它有一個受 better-sqlite3 啟發的 API,但它是用原生程式碼編寫的,速度更快。
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
const query = db.query("select 'Bun' as runtime;");
query.get(); // => { runtime: "Bun" }
Bun 查詢 SQLite 的速度比 Node.js 上的 better-sqlite3 快 4 倍(連結)。
Bun.password
Bun 還支援常見的、但複雜的 API,您不想自己實現。
您可以使用 Bun.password 來使用 bcrypt 或 argon2 對密碼進行雜湊和驗證,無需外部依賴。
const password = "super-secure-pa$$word";
const hash = await Bun.password.hash(password);
// => $argon2id$v=19$m=65536,t=2,p=1$tFq+9AVr1bfPxQdh...
const isMatch = await Bun.password.verify(password, hash);
// => true
Bun 是一個包管理器
即使您不將 Bun 用作執行時,Bun 的內建包管理器也可以加快您的開發工作流程。那些盯著 npm 旋轉圖示等待依賴項安裝的日子已經一去不復返了。
Bun 看起來可能像您習慣使用的包管理器——
bun installbun add <package> [--dev|--production|--peer]bun remove <package>bun update <package>——但它感覺不像。
哇,bun install 速度快得驚人
— Steve (Builder.io) (@Steve8708) 2022 年 8 月 21 日
快到我都不相信它奏效了。我必須盯著控制檯看一會兒,才能完全相信包安裝確實發生了。
使用起來感覺很好,@jarredsumner 真是太棒了。
安裝速度
Bun 的速度比 npm、yarn 和 pnpm 快幾個數量級。它使用全域性模組快取來避免從 npm 登錄檔中重複下載,並使用每個作業系統上可用的最快系統呼叫。
執行指令碼
很有可能,您已經有一段時間沒有直接用 node 執行指令碼了。相反,我們通常使用包管理器來與框架和 CLI 互動來構建我們的應用程式。
npm run dev您可以將 npm run 替換為 bun run,每次執行命令時都可以節省 150 毫秒。
這些數字看起來都很小,但在執行 CLI 時,感知的差異非常巨大。執行 npm run 會明顯示卡頓——

——而 bun run 則感覺是即時的。

而且我們不僅僅是針對 npm。事實上,bun run <command> 比 yarn 和 pnpm 中的相應命令更快。
| 指令碼執行器 | 平均時間 |
|---|---|
npm run | 176ms |
yarn run | 131ms |
pnpm run | 259ms |
bun run | 7ms 🚀 |
Bun 是一個測試執行器
如果您以前用 JavaScript 寫過測試,您可能熟悉 Jest,它開創了“expect”風格的 API。
Bun 有一個內建的測試模組 bun:test,它完全相容 Jest。
import { test, expect } from "bun:test";
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});
您可以使用 bun test 命令執行您的測試。
bun test您還可以獲得 Bun 執行器的所有好處,包括 TypeScript 和 JSX 支援。
從 Jest 或 Vitest 遷移很容易。任何來自 @jest/globals 或 vitest 的匯入都將被內部重新對映到 bun:test,因此即使沒有程式碼更改,一切都能正常工作。
import { test } from "@jest/globals";
describe("test suite", () => {
// ...
});
在對zod的測試套件進行的基準測試中,Bun 的速度比 Jest 快 13 倍,比 Vitest 快 8 倍。
Bun 的匹配器是用快速的原生程式碼實現的——Bun 中的 expect().toEqual() 比 Jest 快 100 倍,比 Vitest 快 10 倍(連結)。
要開始使用,您可以使用 bun test 來加速您的 CI。在 Github Actions 中,請使用官方的oven-sh/setup-bun action。
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: oven-sh/setup-bun@v1
- run: bun test為了讓事情變得更好,Bun 會自動為您的測試失敗添加註解,因此您的 CI 日誌很容易閱讀。
Bun 是一個打包器
Bun 是一個 JavaScript 和 TypeScript 打包器和壓縮器,可用於為瀏覽器、Node.js 和其他平臺打包程式碼。
bun build ./index.tsx --outdir ./build它深受 esbuild 的啟發,並提供相容的外掛 API。
import mdx from "@mdx-js/esbuild";
Bun.build({
entrypoints: ["index.tsx"],
outdir: "build",
plugins: [mdx()],
});
Bun 的外掛 API 是通用的,這意味著它既適用於打包器也適用於執行時。所以前面提到的 .yaml 外掛也可以在這裡使用,以支援打包過程中的 .yaml 匯入。
使用 esbuild 自己的基準測試,Bun 比 esbuild 快 1.75 倍,比 Parcel 2 快 150 倍,比 Rollup + Terser 快 180 倍,比 Webpack 快 220 倍。
由於 Bun 的執行時和打包器是整合的,這意味著 Bun 可以做其他打包器做不到的事情。
Bun 引入了 JavaScript 宏,這是一種在打包時執行 JavaScript 函式的機制。這些函式返回的值直接內聯到您的包中。
import { getRelease } from "./release.ts" with { type: "macro" };
// The value of `release` is evaluated at bundle-time,
// and inlined into the bundle, not run-time.
const release = await getRelease();
export async function getRelease(): Promise<string> {
const response = await fetch(
"https://api.github.com/repos/oven-sh/bun/releases/latest"
);
const { tag_name } = await response.json();
return tag_name;
}
bun build index.ts// index.ts
var release = await "bun-v1.0.0";這是打包 JavaScript 的新範例,我們很期待看到您用它來構建什麼。
Bun 還有其他東西...
Bun 為 macOS 和 Linux 提供了原生構建,但有一個顯著的缺失:Windows。以前,要在 Windows 上執行 Bun,您需要安裝 Windows Subsystem for Linux……但現在不再需要了。
我們很高興首次釋出 Bun 的實驗性原生 Windows 構建。
雖然 Bun 的 macOS 和 Linux 構建已準備好投入生產,但Windows 構建是高度實驗性的。目前只支援 JavaScript 執行時;在包管理器、測試執行器和打包器更穩定之前,它們已被停用。效能也尚未得到最佳化——至今。
在接下來的幾周內,我們將快速改進對 Windows 的支援。如果您對 Bun for Windows 感到興奮,我們鼓勵您加入我們Discord 上的 #windows 頻道以獲取更新。
感謝
Bun 達到 1.0 的旅程離不開 Bun 優秀的工程師團隊和不斷壯大的貢獻者社群。
我們要感謝那些幫助我們走到今天的人。
- Node.js 及其貢獻者:軟體是建立在巨人肩膀上的。
- WebKit 及其貢獻者,特別是Constellation:感謝您讓 WebKit 變得更快,您太棒了。
- 在過去兩年中,近 300 位貢獻者為構建 Bun 提供了幫助!
下一步是什麼?
Bun 1.0 只是一個開始。
我們正在開發一種新的方式來部署 JavaScript 和 TypeScript 到生產環境。並且我們正在招聘低階系統工程師,如果您想幫助我們構建 JavaScript 的未來。
您也可以
- 加入我們的 Discord 伺服器,瞭解 Bun 的最新動態。
- 關注我們在 X/Twitter 上的賬戶,獲取 JavaScript 梗圖以及 Jarred 和團隊的每日更新。
- 點贊我們在 Github 上的倉庫——它能支付賬單!(/s)
安裝 Bun
curl -fsSL https://bun.nodejs.com.tw/install | bashnpm install -g bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bun升級 Bun
bun upgradev0.8 以來的更新日誌
如果您在 1.0 之前就使用 Bun,自 Bun 0.8 以來有一些變化。
- 現在支援 Next.js、Astro 和 Nest.js!
- 已刪除已棄用的
bun dev命令。現在執行bun dev將執行您 package.json 中的"dev"指令碼。
Bun 現在支援以下 Node.js API:
child_process.fork()和 IPC。fs.cp()和fs.cpSync()。fs.watchFile()和fs.unwatchFile()。node:http中的 Unix 套接字。
熱過載現在支援 Bun.serve()。以前,只有當伺服器定義為 default export 時才可能實現這一點。
Bun.serve({
fetch(request) {
return new Response("Reload!");
},
})
bun --hot server.ts