SKILL.md
readonlyread-only
name
bun-development
description
使用 Bun 執行環境進行快速、現代的 JavaScript/TypeScript 開發,靈感來自 [oven-sh/bun](https://github.com/oven-sh/bun)。
⚡ Bun 開發
使用 Bun 執行環境進行快速、現代的 JavaScript/TypeScript 開發,靈感來自 oven-sh/bun。
何時使用此技能
在以下情況使用此技能:
- 使用 Bun 啟動新的 JS/TS 專案
- 從 Node.js 遷移到 Bun
- 最佳化開發速度
- 使用 Bun 內建工具(打包器、測試執行器)
- 排除 Bun 特定問題
1. 開始使用
1.1 安裝
# macOS / Linux
brew install oven-sh/bun/bun
# 替代方案:下載官方安裝程式,檢查後執行
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl -fsSLo "$tmpdir/bun-install.sh" https://bun.sh/install
cat "$tmpdir/bun-install.sh" # 執行前檢查完整安裝程式
bash "$tmpdir/bun-install.sh"
# Windows
powershell -NoProfile -Command "Invoke-WebRequest https://bun.sh/install.ps1 -OutFile $env:TEMP\\bun-install.ps1; Get-Content $env:TEMP\\bun-install.ps1 -TotalCount 120; powershell -ExecutionPolicy Bypass -File $env:TEMP\\bun-install.ps1"
# Homebrew
brew tap oven-sh/bun
brew install bun
# npm(如有需要)
npm install -g bun
# 升級
bun upgrade
1.2 為什麼選擇 Bun?
| 功能 | Bun | Node.js |
|---|---|---|
| 啟動時間 | ~25ms | ~100ms+ |
| 套件安裝 | 快 10-100 倍 | 基準 |
| TypeScript | 原生支援 | 需要轉譯器 |
| JSX | 原生支援 | 需要轉譯器 |
| 測試執行器 | 內建 | 外部(Jest、Vitest) |
| 打包器 | 內建 | 外部(Webpack、esbuild) |
2. 專案設定
2.1 建立新專案
# 初始化專案
bun init
# 建立檔案:
# ├── package.json
# ├── tsconfig.json
# ├── index.ts
# └── README.md
# 使用特定模板
bun create <template> <project-name>
# 範例
bun create react my-app # React 應用程式
bun create next my-app # Next.js 應用程式
bun create vite my-app # Vite 應用程式
bun create elysia my-api # Elysia API
2.2 package.json
{
"name": "my-bun-project",
"version": "1.0.0",
"module": "index.ts",
"type": "module",
"scripts": {
"dev": "bun run --watch index.ts",
"start": "bun run index.ts",
"test": "bun test",
"build": "bun build ./index.ts --outdir ./dist",
"lint": "bunx eslint ."
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
}
2.3 tsconfig.json(Bun 最佳化)
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"allowImportingTsExtensions": true,
"noEmit": true,
"composite": true,
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"types": ["bun-types"]
}
}
3. 套件管理
3.1 安裝套件
# 從 package.json 安裝
bun install # 或 'bun i'
# 新增依賴
bun add express # 一般依賴
bun add -d typescript # 開發依賴
bun add -D @types/node # 開發依賴(別名)
bun add --optional pkg # 選擇性依賴
# 從特定來源安裝
bun add lodash --registry https://registry.npmmirror.com
# 安裝特定版本
bun add react@18.2.0
bun add react@latest
bun add react@next
# 從 Git 安裝
bun add github:user/repo
bun add git+https://github.com/user/repo.git
3.2 移除與更新
# 移除套件
bun remove lodash
# 更新套件
bun update # 更新全部
bun update lodash # 更新特定套件
bun update --latest # 更新到最新(忽略範圍)
# 檢查過期套件
bun outdated
3.3 bunx(相當於 npx)
# 執行套件二進位檔
bunx prettier --write .
bunx tsc --init
bunx create-react-app my-app
# 指定版本
bunx -p typescript@4.9 tsc --version
# 不安裝直接執行
bunx cowsay "Hello from Bun!"
3.4 鎖定檔
# bun.lockb 是二進位鎖定檔(解析更快)
# 若要產生文字鎖定檔以供除錯:
bun install --yarn # 產生 yarn.lock
# 信任現有鎖定檔
bun install --frozen-lockfile
4. 執行程式碼
4.1 基本執行
# 直接執行 TypeScript(無需建置步驟!)
bun run index.ts
# 執行 JavaScript
bun run index.js
# 帶參數執行
bun run server.ts --port 3000
# 執行 package.json 中的腳本
bun run dev
bun run build
# 簡寫(用於腳本)
bun dev
bun build
4.2 監看模式
# 檔案變更時自動重啟
bun --watch run index.ts
# 熱重載
bun --hot run server.ts
4.3 環境變數
// .env 檔案會自動載入!
// 存取環境變數
const apiKey = Bun.env.API_KEY;
const port = Bun.env.PORT ?? "3000";
// 或使用 process.env(Node.js 相容)
const dbUrl = process.env.DATABASE_URL;
# 使用特定 env 檔案執行
bun --env-file=.env.production run index.ts
5. 內建 API
5.1 檔案系統(Bun.file)
// 讀取檔案
const file = Bun.file("./data.json");
const text = await file.text();
const json = await file.json();
const buffer = await file.arrayBuffer();
// 檔案資訊
console.log(file.size); // 位元組
console.log(file.type); // MIME 類型
// 寫入檔案
await Bun.write("./output.txt", "Hello, Bun!");
await Bun.write("./data.json", JSON.stringify({ foo: "bar" }));
// 串流大型檔案
const reader = file.stream();
for await (const chunk of reader) {
console.log(chunk);
}
5.2 HTTP 伺服器(Bun.serve)
const server = Bun.serve({
port: 3000,
fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response("Hello World!");
}
if (url.pathname === "/api/users") {
return Response.json([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
]);
}
return new Response("Not Found", { status: 404 });
},
error(error) {
return new Response(`Error: ${error.message}`, { status: 500 });
},
});
console.log(`Server running at http://localhost:${server.port}`);
5.3 WebSocket 伺服器
const server = Bun.serve({
port: 3000,
fetch(req, server) {
// 升級為 WebSocket
if (server.upgrade(req)) {
return; // 已升級
}
return new Response("Upgrade failed", { status: 500 });
},
websocket: {
open(ws) {
console.log("Client connected");
ws.send("Welcome!");
},
message(ws, message) {
console.log(`Received: ${message}`);
ws.send(`Echo: ${message}`);
},
close(ws) {
console.log("Client disconnected");
},
},
});
5.4 SQLite(Bun.sql)
import { Database } from "bun:sqlite";
const db = new Database("mydb.sqlite");
// 建立資料表
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE
)
`);
// 插入
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("Alice", "alice@example.com");
// 查詢
const query = db.prepare("SELECT * FROM users WHERE name = ?");
const user = query.get("Alice");
console.log(user); // { id: 1, name: "Alice", email: "alice@example.com" }
// 查詢全部
const allUsers = db.query("SELECT * FROM users").all();
5.5 密碼雜湊
// 雜湊密碼
const password = crypto.randomUUID();
const hash = await Bun.password.hash(password);
// 驗證密碼
const isValid = await Bun.password.verify(password, hash);
console.log(isValid); // true
// 搭配演算法選項
const bcryptHash = await Bun.password.hash(password, {
algorithm: "bcrypt",
cost: 12,
});
6. 測試
6.1 基本測試
// math.test.ts
import { describe, it, expect, beforeAll, afterAll } from "bun:test";
describe("Math operations", () => {
it("adds two numbers", () => {
expect(1 + 1).toBe(2);
});
it("subtracts two numbers", () => {
expect(5 - 3).toBe(2);
});
});
6.2 執行測試
# 執行所有測試
bun test
# 執行特定檔案
bun test math.test.ts
# 執行符合模式的測試
bun test --grep "adds"
# 監看模式
bun test --watch
# 含涵蓋率
bun test --coverage
# 逾時
bun test --timeout 5000
6.3 匹配器
import { expect, test } from "bun:test";
test("matchers", () => {
// 相等性
expect(1).toBe(1);
expect({ a: 1 }).toEqual({ a: 1 });
expect([1, 2]).toContain(1);
// 比較
expect(10).toBeGreaterThan(5);
expect(5).toBeLessThanOrEqual(5);
// 真值
expect(true).toBeTruthy();
expect(null).toBeNull();
expect(undefined).toBeUndefined();
// 字串
expect("hello").toMatch(/ell/);
expect("hello").toContain("ell");
// 陣列
expect([1, 2, 3]).toHaveLength(3);
// 例外
expect(() => {
throw new Error("fail");
}).toThrow("fail");
// 非同步
await expect(Promise.resolve(1)).resolves.toBe(1);
await expect(Promise.reject("err")).rejects.toBe("err");
});
6.4 模擬
import { mock, spyOn } from "bun:test";
// 模擬函式
const mockFn = mock((x: number) => x * 2);
mockFn(5);
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith(5);
expect(mockFn.mock.results[0].value).toBe(10);
// 監控方法
const obj = {
method: () => "original",
};
const spy = spyOn(obj, "method").mockReturnValue("mocked");
expect(obj.method()).toBe("mocked");
expect(spy).toHaveBeenCalled();
7. 打包
7.1 基本建置
# 打包成正式環境
bun build ./src/index.ts --outdir ./dist
# 搭配選項
bun build ./src/index.ts \
--outdir ./dist \
--target browser \
--minify \
--sourcemap
7.2 建置 API
const result = await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser", // 或 "bun"、"node"
minify: true,
sourcemap: "external",
splitting: true,
format: "esm",
// 外部套件(不打包)
external: ["react", "react-dom"],
// 定義全域變數
define: {
"process.env.NODE_ENV": JSON.stringify("production"),
},
// 命名
naming: {
entry: "[name].[hash].js",
chunk: "chunks/[name].[hash].js",
asset: "assets/[name].[hash][ext]",
},
});
if (!result.success) {
console.error(result.logs);
}
7.3 編譯成可執行檔
# 建立獨立可執行檔
bun build ./src/cli.ts --compile --outfile myapp
# 跨平台編譯
bun build ./src/cli.ts --compile --target=bun-linux-x64 --outfile myapp-linux
bun build ./src/cli.ts --compile --target=bun-darwin-arm64 --outfile myapp-mac
# 嵌入資源
bun build ./src/cli.ts --compile --outfile myapp --embed ./assets
8. 從 Node.js 遷移
8.1 相容性
// 大部分 Node.js API 可直接使用
import fs from "fs";
import path from "path";
import crypto from "crypto";
// process 是全域變數
console.log(process.cwd());
console.log(process.env.HOME);
// Buffer 是全域變數
const buf = Buffer.from("hello");
// __dirname 和 __filename 可用
console.log(__dirname);
console.log(__filename);
8.2 常見遷移步驟
# 1. 安裝 Bun
brew install oven-sh/bun/bun
# 2. 取代套件管理員
rm -rf node_modules package-lock.json
bun install
# 3. 更新 package.json 中的腳本
# "start": "node index.js" → "start": "bun run index.ts"
# "test": "jest" → "test": "bun test"
# 4. 加入 Bun 類型定義
bun add -d @types/bun
8.3 與 Node.js 的差異
// ❌ Node.js 特定(可能無法運作)
require("module") // 請改用 import
require.resolve("pkg") // 請改用 import.meta.resolve
__non_webpack_require__ // 不支援
// ✅ Bun 對應方式
import pkg from "pkg";
const resolved = import.meta.resolve("pkg");
Bun.resolveSync("pkg", process.cwd());
// ❌ 這些全域變數不同
process.hrtime() // 請改用 Bun.nanoseconds()
setImmediate() // 請改用 queueMicrotask()
// ✅ Bun 專屬功能
const file = Bun.file("./data.txt"); // 快速檔案 API
Bun.serve({ port: 3000, fetch: ... }); // 快速 HTTP 伺服器
Bun.password.hash(password); // 內建雜湊功能
9. 效能建議
9.1 使用 Bun 原生 API
// 慢(Node.js 相容)
import fs from "fs/promises";
const content = await fs.readFile("./data.txt", "utf-8");
// 快(Bun 原生)
const file = Bun.file("./data.txt");
const content = await file.text();
9.2 使用 Bun.serve 處理 HTTP
// 不要:Express/Fastify(有額外負擔)
import express from "express";
const app = express();
// 要:Bun.serve(原生,快 4-10 倍)
Bun.serve({
fetch(req) {
return new Response("Hello!");
},
});
// 或使用 Elysia(Bun 最佳化框架)
import { Elysia } from "elysia";
new Elysia().get("/", () => "Hello!").listen(3000);
9.3 為正式環境打包
# 正式環境務必打包並壓縮
bun build ./src/index.ts --outdir ./dist --minify --target node
# 然後執行打包後的檔案
bun run ./dist/index.js
快速參考
| 任務 | 指令 |
|---|---|
| 初始化專案 | bun init |
| 安裝依賴 | bun install |
| 新增套件 | bun add <pkg> |
| 執行腳本 | bun run <script> |
| 執行檔案 | bun run file.ts |
| 監看模式 | bun --watch run file.ts |
| 執行測試 | bun test |
| 建置 | bun build ./src/index.ts --outdir ./dist |
| 執行套件 | bunx <pkg> |
資源
限制
- 僅在任務明確符合上述範圍時使用此技能。
- 請勿將輸出視為環境特定驗證、測試或專家審查的替代方案。
- 若缺少必要輸入、權限、安全邊界或成功標準,請停止並要求釐清。






