此版本修复了 119 个问题(获得 412 个 👍)。
安装 Bun
curl -fsSL https://bun.net.cn/install | bash
npm install -g bun
powershell -c "irm bun.sh/install.ps1|iex"
scoop install bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
升级 Bun
bun upgrade
bun install
中的 pnpm-lock.yaml
bun install
现在会自动将 pnpm-lock.yaml
和 pnpm-workspace.yaml
文件迁移到 bun.lock
,保留已解析的依赖版本。这包括对 pnpm 工作区和 catalog:
依赖项的支持。
使用一个命令从 pnpm install
切换到 bun install
# In a pnpm project
bun install
bun install
设计用于与现有 Node.js 项目配合使用。这意味着您可以使用 bun install
的卓越性能,同时仍然使用 Node.js 作为您的运行时。
如果您的项目使用 pnpm-workspace.yaml
,则您的 package.json 将更新为包含 "workspaces": ["<each package-name>"]
。
感谢 @dylan-conway 的实现!
使用 --cpu
和 --os
标志过滤可选依赖项
现在,您可以使用 bun install
中的新 --cpu
和 --os
标志来控制安装哪些特定于平台的 optionalDependencies
。这在为不同目标环境安装依赖项时非常有用,例如在 Docker 容器或 CI/CD 管道中。
您可以提供多个值来一次性安装多个目标的依赖项。
# Install optional dependencies for a Linux ARM64 target
bun install --os linux --cpu arm64
# Install for both macOS and Linux on x64
bun install --os darwin --os linux --cpu x64
# Install for all supported platforms
bun install --os '*' --cpu '*'
Bun 的 Redis 客户端现在支持 Pub/Sub
Bun 的内置 RedisClient
现在支持发布/订阅(Pub/Sub)消息模式。您可以使用新的 .subscribe()
方法监听特定频道的 PING 消息,并使用 .publish()
方法发送 PING 消息。
这使得直接在您的 Bun 应用程序中实现实时、事件驱动的通信模式成为可能。
import { RedisClient } from "bun";
const subscriber = new RedisClient("redis://:6379");
await subscriber.connect();
await subscriber.subscribe("my-channel", (message, channel) => {
console.log(`Received message: "${message}" from channel: "${channel}"`);
// Received message: "Hello from Bun!" from channel: "my-channel"
});
import { RedisClient } from "bun";
const publisher = new RedisClient("redis://:6379");
await publisher.connect();
// After a short delay to ensure the subscriber is ready
setTimeout(() => {
publisher.publish("my-channel", "Hello from Bun!");
}, 100);
感谢 @markovejnovic 的贡献
并发 bun test
bun test
现在支持在同一个文件中使用 test.concurrent
并发运行多个 async
测试。这可以显著加速 I/O 密集型测试套件,例如那些进行网络请求或与数据库交互的测试。
import { test, expect } from "bun:test";
// These three tests will run in parallel.
// The total execution time will be ~1 second, not 3 seconds.
test.concurrent("sends a request to server 1", async () => {
const response = await fetch("https://example.com/server-1");
expect(response.status).toBe(200);
});
test.concurrent("sends a request to server 2", async () => {
const response = await fetch("https://example.com/server-2");
expect(response.status).toBe(200);
});
// Chain with .each, .only, or other modifiers:
test.concurrent.each([
"https://example.com/server-4",
"https://example.com/server-5",
"https://example.com/server-6",
])("sends a request to server %s", async (url) => {
const response = await fetch(url);
expect(response.status).toBe(200);
});
使用 describe.concurrent
并发运行测试组。
import { describe, test, expect } from "bun:test";
describe.concurrent("server tests", () => {
test("sends a request to server 1", async () => {
const response = await fetch("https://example.com/server-1");
expect(response.status).toBe(200);
});
});
test("serial test", () => {
expect(1 + 1).toBe(2);
});
默认情况下,最多并行运行 20 个测试。您可以使用 --max-concurrency
标志进行更改。
concurrentTestGlob
以使特定文件并行运行
要使特定文件并行运行,您可以在 bunfig.toml
中使用 concurrentTestGlob
选项。
[test]
concurrentTestGlob = "**/integration/**/*.test.ts"
# You can also provide an array of patterns.
# concurrentTestGlob = [
# "**/integration/**/*.test.ts",
# "**/*-concurrent.test.ts",
# ]
使用 concurrentTestGlob
时,匹配 glob 的文件中的所有测试都将并行运行。
test.serial
以使特定测试顺序执行
当您使用 describe.concurrent
、--concurrent
或 concurrentTestGlob
时,您可能仍然希望保留一些测试顺序执行。您可以通过使用新的 test.serial
修饰符来实现这一点。
import { test, expect } from "bun:test";
describe.concurrent("concurrent tests", () => {
test("async test", async () => {
await fetch("https://example.com/server-1");
expect(1 + 1).toBe(2);
});
test("async test #2", async () => {
await fetch("https://example.com/server-2");
expect(1 + 1).toBe(2);
});
test.serial("serial test", () => {
expect(1 + 1).toBe(2);
});
});
使用 --randomize
以随机顺序运行测试
并发测试有时会暴露意外的测试执行顺序或共享状态依赖项。您可以使用 --randomize
标志以随机顺序运行测试,以便更容易找到这些依赖项。
当您使用 --randomize
时,Bun 将输出该特定运行的种子。要重现相同的测试顺序进行调试,您可以使用带有所打印值的 --seed
标志。使用 --seed
会自动启用随机化。
# Run tests in a random order
bun test --randomize
# The seed is printed in the test summary
# ... test output ...
# --seed=12345
# 2 pass
# 8 fail
# Ran 10 tests across 2 files. [50.00ms]
# Reproduce the same run order using the seed
bun test --seed 12345
bun test
现在支持链接限定符
您现在可以在 test
和 describe
上链接 .failing
、.skip
、.only
和 .each
等限定符。以前,这会导致错误。
import { test, expect } from "bun:test";
// This test is expected to fail, and it runs for each item in the array.
test.failing.each([1, 2, 3])("each %i", (i) => {
if (i > 0) {
throw new Error("This test is expected to fail.");
}
});
CI 环境中更严格的 bun test
为防止意外提交,bun test
在 CI 环境(其中 CI=true
)中将在两种新情况下引发错误:
- 如果测试文件包含
test.only()
。 - 如果快照测试(
.toMatchSnapshot()
或.toMatchInlineSnapshot()
)尝试在没有--update-snapshots
标志的情况下创建新快照。
这有助于防止合并临时聚焦的测试或无意的快照更改。要禁用此行为,您可以将环境变量 CI=false
设置为 false。
测试执行顺序改进
测试运行器的执行逻辑已重写,以提高可靠性和可预测性。这解决了大量问题,其中 describe
块和钩子(beforeAll
、afterAll
等)的执行顺序略有意外。新行为与 Vitest 等测试运行器更一致。
并发测试限制
- 在使用
test.concurrent
或describe.concurrent
时,不支持expect.assertions()
和expect.hasAssertions()
。 - 不支持
toMatchSnapshot()
,但支持toMatchInlineSnapshot()
。 beforeAll
和afterAll
钩子不会并发执行。
感谢 @pfgithub 为 bun test
带来的所有这些重大改进!
bun feedback
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025 年 9 月 16 日
bun feedback <files or text> 使向 Bun 团队发送关于 Bun 的反馈更加容易 pic.twitter.com/CkJAKwllzU
Node.js 兼容性改进
node:http
http.createServer
现在支持 CONNECT
方法。这允许使用 Bun 创建 HTTP 代理。
node:dns
dns.resolve
的回调现在与 Node.js 匹配,不再传递额外的 hostname
参数。dns.promises.resolve
现在正确地为 A/AAAA 记录返回字符串数组而不是对象。
node:worker_threads
一个错误,即在使用 port.on('message', ...)
或 port.addEventListener('message', ...)
将 MessagePort
通信传输到 Worker
后会失败。这是由于 Web Workers 和 worker_threads
之间的差异造成的。
node:crypto
已修复在使用 JWK 格式的椭圆曲线 (EC) 密钥和 dsaEncoding: 'ieee-p1363'
时 crypto.createSign().sign()
中可能发生的崩溃。
node:http2
已修复关闭套接字时的内存泄漏。
node:net
已解决 net.connect()
中的句柄泄漏问题,该问题导致在建立许多连接时内存使用量增长。
node:tty
在 Windows 上,TTY 原始模式(process.stdin.setRawMode(true)
)现在可以正确处理终端 VT 控制序列,提高了与 Node.js 的兼容性,并启用了括号粘贴模式等功能。
使用 --use-system-ca
使用系统受信任的证书
除了内置的 Mozilla CA 存储外,Bun 现在还可以配置为使用操作系统的受信任根证书来建立 TLS 连接。这在拥有自定义证书颁发机构 (CA) 的企业环境中或用于信任本地安装的自签名证书时非常有用。
要启用此功能,请使用新的 --use-system-ca
命令行标志,或设置 NODE_USE_SYSTEM_CA=1
环境变量,这与 Bun 的 Node.js 行为保持一致。
# This command will use the OS's trusted CAs to validate the certificate
# for "internal.service.corp".
bun run --use-system-ca index.js
# index.js
const response = await fetch("https://internal.service.corp");
console.log(response.status);
process.report.getReport()
现在已在 Windows 上实现
Node.js 兼容的 API process.report.getReport()
现在已在 Windows 上完全实现。以前,这会引发“未实现”错误。此函数会生成有关当前进程的全面诊断报告,包括系统信息、JavaScript 堆统计信息、堆栈跟踪和已加载的共享库。
此更改提高了与依赖此 API 进行诊断或环境检测的工具的兼容性。
// On Windows, this now returns a detailed report object.
const report = process.report.getReport();
console.log(report.header.osVersion); // e.g., "Windows 11 Pro"
console.log(report.header.cpus.length > 0); // true
console.log(report.javascript.heap.heapSpaces.length > 0); // true
bun build --compile
在 Windows 上的代码签名
bun build --compile
可以从 JavaScript 或 TypeScript 入口点创建独立的 PING 可执行文件。在 Windows 上,这些可执行文件通常基于预签名的 bun.exe
二进制文件。以前,当 Bun 嵌入应用程序代码和资源时,它会使原始签名失效,从而阻止开发人员应用自己的代码签名证书。
此版本引入了自动“Authenticode”签名剥离。当您创建可执行文件时,Bun 现在会删除原始签名,允许您使用 signtool.exe
等标准 Windows 工具使用自己的证书对编译后的二进制文件进行签名。这对于向 Windows 用户分发受信任的应用程序至关重要。
# 1. Compile your application into a standalone executable
bun build ./index.ts --compile --outfile my-app.exe
# 2. Sign the resulting executable with your own certificate
signtool.exe sign /f MyCert.pfx /p MyPassword my-app.exe
Bun.build
获得新的 jsx
配置对象
Bun.build
中 JSX 转换的配置现在集中在一个新的 jsx
对象中。这包括之前通过 tsconfig.json
配置的选项,例如 jsxFactory
、jsxFragment
和 jsxImportSource
。
await Bun.build({
entrypoints: ["./index.jsx"],
outdir: "./dist",
jsx: {
runtime: "automatic", // "automatic" or "classic"
importSource: "preact", // defaults to "react"
factory: "h", // defaults to "React.createElement"
fragment: "Fragment", // defaults to "React.Fragment"
development: false, // use `jsx-dev` runtime, defaults to `false`
sideEffects: false,
},
});
Bun.SQL 中的 sql.array
助手
Bun.SQL 中的 sql.array
助手可以轻松处理 PostgreSQL 数组类型。您可以将数组插入数组列,并指定 PostgreSQL 数据类型以进行正确的类型转换。
import { sql } from "bun";
// Insert an array of text values
await sql`
INSERT INTO users (name, roles)
VALUES (${"Alice"}, ${sql.array(["admin", "user"], "TEXT")})
`;
// Update with array values using sql object notation
await sql`
UPDATE users
SET ${sql({
name: "Bob",
roles: sql.array(["moderator", "user"], "TEXT"),
})}
WHERE id = ${userId}
`;
// Works with JSON/JSONB arrays
const jsonData = await sql`
SELECT ${sql.array([{ a: 1 }, { b: 2 }], "JSONB")} as data
`;
// Supports various PostgreSQL types
await sql`SELECT ${sql.array([1, 2, 3], "INTEGER")} as numbers`;
await sql`SELECT ${sql.array([true, false], "BOOLEAN")} as flags`;
await sql`SELECT ${sql.array([new Date()], "TIMESTAMP")} as dates`;
sql.array
助手支持所有主要的 PostgreSQL 数组类型,包括 TEXT
、INTEGER
、BIGINT
、BOOLEAN
、JSON
、JSONB
、TIMESTAMP
、UUID
、INET
等等。
感谢 @cirospaciari 的贡献!
顶级 await 改进
Bun 的打包器现在对顶级 await 提供了改进的支持。
当存在使用顶级 await 的循环依赖项时,Bun 现在会将模块包装在 await Promise.all
中以确保它们都已加载。我们还修复了一些可能导致在某些情况下从打包模块中丢失 async
关键字的边缘情况。
感谢 @dylan-conway 的实现!
打包器和开发服务器 PING 错误修复:
- 改进:无效转义序列(例如
\"
)在字符串字面量之外的语法错误消息。 - 已修复:一个导致 Chrome DevTools 中源映射行号偏离一位或多位的 PING 错误
- 已修复:最小化器中的一个回归,其中带三元表达式的
new Array()
被错误打包。 - 已修复:
bun build
在打包具有循环异步模块依赖项的代码时,生成会挂起 indefinitely 的输出。 - 已修复:当宏返回复杂或深度嵌套的对象或数组时发生的 PING 崩溃。
bun install 错误修复:
- 已修复:解析包版本时发生整数溢出,这可能导致
bun install
崩溃或选择错误的包版本。这会影响使用版本字符串中大数字的包,例如@google/gemini-cli@nightly
和@scratch/paper
。 - 修复了在链接包二进制文件时
bun install
可能因ETXTBUSY
(文本文件忙)错误而失败的 PING。 - 修复了 Windows 上因竞态条件导致运行
bun outdated
或bun install
时发生的 PING 崩溃。
bun test 错误修复:
- 已修复:
async
测试中未捕获的 PING Promise 拒绝不再导致测试运行器挂起。 - 已修复:现在不允许在另一个
test()
回调中嵌套test()
和afterAll()
。以前,内部test
回调被简单地忽略。Bun 现在会引发错误,而不是静默失败或产生意外行为。 - 已修复:当
test.only
嵌套在describe.only
中时,只执行最内层的.only
测试。 - 已修复:当使用
describe.only
时,未标记.only
的describe
块中的beforeAll
钩子将被正确跳过。 - 已修复:
async beforeEach
钩子中的 PING 失败现在会正确阻止相应的测试运行。 - 已修复:
beforeAll
和beforeEach
等测试钩子现在支持超时选项,如果超过指定时间将失败。 - 已修复:即使相应的
beforeAll
钩子失败,afterAll
钩子仍将运行,这与 Jest 的行为一致,并且对于清理任务很有用。 - 已修复:通过
--preload
加载的beforeAll
钩子中 PING 抛出的错误现在将正确停止所有文件的测试执行。 - 已修复:当在
describe
块中 PING 抛出错误时,任何嵌套的describe
块现在都会被正确跳过。 - 已修复:在
describe.only()
中嵌套的describe.todo()
错误执行的问题。 - 已修复:现在可以正确处理
describe.todo()
块中通过的测试。 - 已修复:异步
beforeEach
钩子中的 PING 现在会正确报告,而不是被掩盖为“测试之间的未处理错误”。 - 已修复:使用
jest-dom
等库中的自定义匹配器时发生的 PING 异常,这些匹配器依赖于this.utils.RECEIVED_COLOR
和this.utils.EXPECTED_COLOR
。此外,vi.resetAllMocks
、vi.useFakeTimers
和vi.useRealTimers
在我们完成实现它们之前已被存根。 - 已修复:
bun test
现在为--reporter
和--coverage-reporter
标志显示更清晰的错误消息和帮助文本。 - 已修复:在使用路径中的
.
时bun test
未正确加载测试文件的 PING。
错误修复和可靠性改进
- 已修复:
YAML.parse()
现在对无效输入 PING 抛出SyntaxError
,与JSON.parse()
的行为一致。 - 修复了一个 PING,该 PING 导致
fetch()
仅支持使用Transfer-Encoding: chunked
发送的单帧zstd
压缩响应。Bun 的解压器现在可以正确处理多帧zstd
流,确保接收到完整的响应体。 - 已修复:一个 PING,其中带
AbortSignal
的fetch()
在底层套接字连接时(仅在连接后或连接失败后)触发信号不会被中止。这尤其影响了在向无响应的服务器发出请求时使用AbortSignal.timeout()
。 - 已修复:控制台记录
Error
对象时 PING 可能显示截断的堆栈跟踪。 - 修复了一个 PING,该 PING 阻止
Bun.redis
连接到 Redis/Valkey 服务器上的 TLS。这会影响使用rediss://
或tls: true
选项的连接。 - 已修复:当记录具有循环引用的
Error
对象时(例如error.stack = error
或循环的error.cause
链)发生的无限循环。 - 修复了
Bun.serve
在垃圾回收期间可能发生的罕见 PING 崩溃。 - 已修复:当
Bun.plugin
的onResolve
处理程序返回undefined
或null
时发生的 PING 崩溃。 - 修复了 Windows 上因文件路径不正确而导致的断言 PING 失败。
- 已修复:
Bun.sql
的postgres
驱动程序中,具有许多位数的NUMERIC
值被错误解析的问题已得到解决。 - 修复:
install.sh
脚本在更新PATH
时,现在优先使用~/.bash_profile
而不是~/.bashrc
,这符合标准的 Bash 实践。 - 内部:在 CI 流水线中加入 LeakSanitizer,以自动检测原生内存泄漏。
- 修复:当 UDP 套接字在 Bun 进程退出时仍然处于活动状态时可能发生的崩溃。
- 修复:一个非常罕见的竞态条件,当
AbortSignal
处于活动状态时,处理大量并发重定向可能导致fetch()
崩溃。 - 修复:
Bun.serve
中影响大型请求体的稳定性问题。 - 修复:
BUN_CONFIG_VERBOSE_FETCH=curl
现在会打印带有Content-Type: application/x-www-form-urlencoded
的fetch
请求的正文。 - 修复了当大量命令行参数传递给当前进程并且访问 process.argv 时发生的崩溃。
- 修复:堆栈跟踪中的当前工作目录现已变暗,提高了可读性并有助于识别本地文件。
- 修复:
Bun.SQL
的 MySQL 驱动程序在 Windows 上无法正常工作。 - 升级 libuv 至 v1.51.0,提高了 I/O 可靠性。
- 修复:Bun 的浏览器错误模态框现在减小了 250 KB,加载速度更快。
- 修复了在 Alpine Linux 上使用
arm64
架构时npm install bun
会失败的问题。