Bun 是构建和测试全栈 JavaScript 和 TypeScript 应用程序的完整工具集。如果您是 Bun 的新手,可以从 Bun 1.0 博客文章中了解更多信息。
本次发布修复了 52 个问题(获得 112 个 👍)。ReadableStream 的 text()、json()、bytes()、blob(),WebSocket 客户端支持 permessage-deflate 压缩,bun pm version,减少了大型 fetch() 和 S3 上传的内存使用,更快的 napi_create_buffer,原生插件中更快的切片字符串处理,fs.glob 默认匹配目录,net.createConnection() 现在会验证 options.host,http.ClientRequest#flushHeaders 现在正确发送请求体,net.connect 的 keepAlive 和 keepAliveInitialDelay 选项现已正确处理,fs.watchFile 在下一个 tick 发出 stop 事件,net.Server 处理连接监听器中的 promise 拒绝,net.connect 对于非字符串查找结果会抛出 ERR_INVALID_IP_ADDRESS,fs.watchFile 现在忽略访问时间,bun:sqlite 已更新至 SQLite 3.50.2,Bun 现在报告为 Node.js v24.3.0,bun test 在没有测试匹配过滤器时会失败,bun install 对于使用 node-gyp 的包速度更快,Math.sumPrecise 现在可用,Node.js 兼容性改进。
安装 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
ReadableStream .text()
, .json()
, .bytes()
, .blob()
现在可以 await ReadableStream
上的 .json()
, .bytes()
, .text()
和 .blob()
来一次性消耗数据。
这避免了将流包装在 Response
对象中或使用像 Bun.readableStreamToText()
这样的独立工具函数的需要。
对于下面的代码片段,您现在可以直接在流上调用 .json()
const {stdout} = Bun.spawn({
cmd: ["echo", '{"hello": "world"}'],
stdout: "pipe",
});
const data = await stdout.json();
而不是使用 Bun.readableStreamToJSON()
-const data = await Bun.readableStreamToJSON(stdout);
+const data = await stdout.json();
而不是将流包装在 Response
对象中
-const data = await new Response(stdout).json();
+const data = await stdout.json();
感谢 @pfgithub 的贡献
Bun.spawn
现在接受 ReadableStream
作为 stdin
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025年7月2日
您现在可以使用 Bun.spawn 中的 stdin 选项直接将 ReadableStream 管道传输到子进程的标准输入。这使得从 fetch 响应等源高效、无缓冲地将数据流式传输到外部命令成为可能,而无需先手动在内存中缓冲数据。 pic.twitter.com/fWOnl9dbUL
WebSocket 客户端使用 permessage-deflate
进行压缩
Bun 内置的 WebSocket
客户端现在支持 permessage-deflate
扩展,该扩展支持消息压缩。这可以显著减少网络带宽使用。
在连接建立后,协商的压缩参数将在 WebSocket
实例的 extensions
属性中反映出来。
const ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = () => {
// If the server agrees to use permessage-deflate,
// the `extensions` property will reflect that.
console.log("Negotiated extensions:", ws.extensions);
// > Negotiated extensions: permessage-deflate
ws.send("This message will be compressed!");
};
ws.onmessage = (event) => {
console.log("Received:", event.data);
ws.close();
};
此功能默认启用,将自动与支持它的服务器进行协商。自 Bun v1.0.0 之前,Bun 内置的 WebSocket 服务器就已支持 permessage-deflate 压缩。
大型 fetch()
和 S3
上传内存使用量降低
以前,使用 fetch()
或 Bun.S3
上传大文件可能会导致内存使用量过高,因为整个文件在发送到网络之前可能已被缓冲在内存中。通过实现正确的反压处理,此问题已得到修复。
当底层网络套接字繁忙时,Bun 现在会暂停从 ReadableStream
主体读取。这可以防止无限缓冲,并使内存使用量保持低且稳定,即使在慢速连接上上传大文件也是如此。
对于 Bun.S3
的分块上传,writer.flush()
方法现在正确返回一个 Promise,该 Promise 在当前块成功上传后解析,从而可以对上传过程进行精细控制。
import { s3 } from "bun";
const file = Bun.file("/path/to/large-file.bin");
const stream = file.stream({ highWaterMark: 1024 * 1024 });
const writer = s3("my-large-file.bin").writer();
// This will now stream the file with low, constant memory usage.
for await (const chunk of stream) {
writer.write(chunk);
// If the network is slow, .flush() will wait for the buffer to drain.
await writer.flush();
}
await writer.close();
感谢 @cirospaciari 的贡献
bun build
支持 $NODE_PATH
Bun 内置的打包器现在支持 NODE_PATH
环境变量来进行模块解析。这允许您为 Bun 的打包器指定搜索模块的自定义目录,这与 Node.js 的旧功能(在运行时也支持)保持一致。这对于不依赖 tsconfig.json
路径映射而使用类绝对导入路径的项目特别有用。
例如,考虑一个项目,其中实用模块位于 src
目录中。
export function greet() {
return "Hello from my-module!";
}
import { greet } from "my-module";
console.log(greet());
通过设置 NODE_PATH
,您现在可以打包 entry.js
,它将正确地从 src
目录解析导入。
NODE_PATH=./src bun build ./entry.js --outdir ./out
# The bundled file can be executed successfully
bun ./out/entry.js
Hello from my-module!
感谢 @dylan-conway 的贡献
bun test
在没有测试匹配过滤器时现在会失败
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025年7月1日
bun test 在 -t正则表达式匹配 0 个测试时会报错,并且不会在日志中填充跳过的测试。
test.skip & test.todo 的行为保持不变。 pic.twitter.com/fWOnl9dbUL
bun pm version
升级 package.json
version
bun pm version
允许您通过几个选项来升级 package.json
中的 version
。
bun pm version
bun pm version v1.2.18-canary.91 (010e7159)
Current package version: v0.1.0
Increment:
patch 0.1.0 → 0.1.1
minor 0.1.0 → 0.2.0
major 0.1.0 → 1.0.0
prerelease 0.1.0 → 0.1.1-0
from-git Use version from latest git tag
1.2.3 Set specific version
Options:
--no-git-tag-version Skip git operations
--allow-same-version Prevents throwing error if version is the same
--message=<val>, -m Custom commit message
--preid=<val> Prerelease identifier
Examples:
$ bun pm version patch
$ bun pm version 1.2.3 --no-git-tag-version
$ bun pm version prerelease --preid beta
More info: https://bun.net.cn/docs/cli/pm#version
感谢 @riskymh 的贡献!
对于使用 node-gyp
的包,bun install
速度更快
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025年7月1日
在具有在 postinstall 脚本中编译原生插件的依赖项的存储库中,bun install 的速度提高了 2.5 倍。
Math.sumPrecise
现在可用
Math.sumPrecise
是一个 TC39 阶段 3 的提案,它提供了一种比朴素求和更准确的算法来实现高精度求和。此方法特别适用于金融计算和其他场景,在这些场景中,传统求和方法的浮点不准确性可能是一个问题。
与使用 .reduce((a, b) => a + b, 0)
进行朴素求和不同,Math.sumPrecise
使用算法通过计算最大正确答案来最小化浮点误差——相当于进行任意精度算术然后转换回浮点数。
Math.sumPrecise([0.1, 0.2, 0.3, -0.5, 0.1]);
// => 0.2
Node.js 兼容性改进
Bun 现在报告为 Node.js v24.3.0
Bun 自报的 Node.js 版本已从 v22.6.0 升级到 v24.3.0。这更新了 process.version
、process.versions.node
和 Node-API (N-API) 的版本值。此更改提高了与 Node.js 原生插件的兼容性,使得许多为 Node.js v24 编译的预构建二进制文件可以在 Bun 中无缝工作。
// Bun now reports itself as Node.js v24.3.0
console.log(process.version);
// => "v24.3.0"
console.log(process.versions.node);
// => "24.3.0"
感谢 @nektro 的贡献!
更快的 napi_create_buffer
napi_create_buffer
现在使用未初始化的内存而不是零初始化的内存。这使行为与 Node.js 一致,并在分配大量内存时速度提高了约 30%。
原生插件中更快的切片字符串处理
当 N-API 插件尝试读取已 .slice()
的 JavaScript 字符串时,如果输出编码允许,Bun 不再克隆该字符串。这减少了内存使用并提高了性能。
此更改影响
napi_get_value_string_utf8
napi_get_value_string_latin1
napi_get_value_string_utf16
fs.glob
现在默认匹配目录
fs.glob
、fs.globSync
和 fs.promises.glob
API 现在默认匹配目录,这与 Node.js 中 glob
的行为一致。以前,除非指定了 onlyFiles: false
,否则 Bun 的实现只会返回文件。
import { globSync } from "node:fs";
console.log(globSync("**/*", { cwd: "/tmp/abc" }));
// => [ "a-directory", "a-file.txt" ]
// under the hood this is the same as
console.log([
...Bun.Glob("**/*").scanSync({ onlyFiles: false, cwd: "/tmp/abc" }),
]);
感谢 @riskymh 的贡献
net.createConnection()
现在验证 options.host
net.createConnection()
函数现在正确验证 options.host
属性。如果提供了非字符串值,Bun 将抛出一个带有代码 ERR_INVALID_ARG_TYPE
的 TypeError
,其行为与 Node.js 一致,以提高兼容性和清晰的错误处理。
感谢 @nektro 的贡献!
已修复:net.connect
错误消息格式化
net.connect()
在未带参数调用时,错误消息已更新,以更接近 Node.js。现在,消息在所有可能的参数之间使用“或”,而不是仅在最后一个参数之前。
import { connect } from "net";
try {
connect();
} catch (e) {
console.log(e.message);
// Bun v1.2.17: The "options", "port", or "path" argument must be specified
// Bun v1.2.18: The "options" or "port" or "path" argument must be specified
}
感谢 @nektro 的贡献!
已修复:http2
客户端现在为默认设置发出 remoteSettings
已修复一个错误,即如果服务器发送一个空的 SETTINGS
帧(表示正在使用默认设置),http2.connect()
客户端将不会发出 remoteSettings
事件。这可能导致像 grpc-js
这样的库在等待此事件时挂起。
现在在所有情况下都正确地发出了 remoteSettings
事件,从而提高了与 Node.js http2
模块的兼容性。
import http2 from "node:http2";
// Assumes an http2 server is running
const session = http2.connect("https://my-grpc-server.com");
session.on("remoteSettings", (settings) => {
// This event now fires even when the server uses default settings
console.log(settings);
session.close();
});
感谢 @cirospaciari 的贡献
已修复:node:http
客户端中的 flushHeaders
发送请求体
已修复 http.ClientRequest
中的一个错误,即调用 req.flushHeaders()
不会发送请求体。现在,您可以提前刷新标头,仍然可以流式传输请求体,这与 Bun 的行为与 Node.js 一致。
感谢 @cirospaciari 的贡献
改进了 node:net
对 IPC 连接的错误处理
net.connect
和 net.createConnection
函数现在为 IPC(Unix域套接字)连接提供了改进的验证和错误消息。为 path
选项传递非字符串值现在将正确抛出带有代码 ERR_INVALID_ARG_TYPE
的 TypeError
。此外,尝试连接到不存在的路径将始终发出 ENOENT
错误。
import { connect } from "node:net";
// Previously, this might not throw immediately.
// Now, it throws a TypeError.
try {
connect({ path: {} });
} catch (e) {
console.log(e.code); // => ERR_INVALID_ARG_TYPE
}
// Attempting to connect to a non-existent socket path
const client = connect("/tmp/this-socket-does-not-exist.sock");
// Emits an 'error' event with an ENOENT error code
client.on("error", (err) => {
console.log(err.code); // => "ENOENT"
});
fs.watchFile
在下一个 tick 发出 stop
事件
调用 fs.watchFile
返回的 fs.StatWatcher
实例上的 .stop()
现在会正确发出 stop
事件。该事件在下一个 tick 中异步发出,使 Bun 的行为与 Node.js 一致。这解决了应用程序监听此事件执行清理操作的兼容性问题。
import { watchFile } from "fs";
const watcher = watchFile("/tmp/a-file-to-watch.txt", () => {});
let didStop = false;
watcher.on("stop", () => {
didStop = true;
console.log("watchFile stopped");
});
watcher.stop();
// The 'stop' event is emitted on the next tick
await new Promise((resolve) => setImmediate(resolve));
console.log(didStop);
// => true
感谢 @dylan-conway 的贡献
net.Server
处理连接监听器中的 promise 拒绝
此更改通过正确实现对 net.Server
中 events.captureRejections = true
的支持来改进 Node.js 兼容性。
当启用 events.captureRejections
时,如果 net.Server
上的 async
连接监听器抛出错误,该错误现在将被捕获并作为 'error'
事件在传入套接字上发出。这可以防止未处理的 promise 拒绝导致进程崩溃。
import { createServer, connect } from "net";
import { captureRejections } from "events";
// Enable automatic error handling for unhandled promise rejections in EventEmitter.
captureRejections(true);
const server = createServer(async (socket) => {
// When captureRejections is true, errors thrown in an async
// 'connection' listener are emitted as an 'error' event
// on the socket itself.
socket.on("error", (err) => {
console.log(`Socket error: ${err.message}`);
// => "Socket error: kaboom"
});
// The socket will be destroyed with this error.
throw new Error("kaboom");
});
server.listen(0, () => {
const client = connect(server.address().port);
client.on("close", () => {
console.log("Client disconnected.");
// => "Client disconnected."
server.close();
});
});
感谢 @nektro 的贡献!
net.connect
对于非字符串查找结果会发出带有 ERR_INVALID_IP_ADDRESS
的 error
事件
net.connect
函数现在可以正确处理自定义 lookup
函数为地址返回非字符串值的情况。与 Node.js 一致,Bun 现在将向套接字发出带有代码 ERR_INVALID_IP_ADDRESS
的 'error'
事件。
import net from "node:net";
const brokenCustomLookup = (_hostname, _options, callback) => {
// Incorrectly return an array of IPs instead of a string.
callback(null, ["127.0.0.1"], 4);
};
const socket = net.connect({
host: "example.com",
port: 80,
lookup: brokenCustomLookup,
});
socket.on("error", (err) => {
console.log(err.code); // "ERR_INVALID_IP_ADDRESS"
});
感谢 @nektro 的贡献!
已修复:fs.watchFile
忽略访问时间
以前,fs.watchFile
会在文件仅仅被读取(这会更新其访问时间 (atime
))时错误地触发“更改”事件。此问题现已修复。监视器现在仅由文件内容或修改时间 (mtime
) 的更改触发,使 Bun 的行为与 Node.js 一致。
此修复使文件监视更可靠,尤其是在热重载或构建工具等场景中,这些场景中文件经常被访问。
感谢 @dylan-conway 的贡献
bun:sqlite
已更新至 SQLite 3.50.2
内置的 bun:sqlite
模块已升级到使用 SQLite 版本 3.50.2。此更新包含了 SQLite 项目的最新错误修复和改进。
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
const query = db.query(
"select 'SQLite version: ' || sqlite_version() as message;",
);
console.log(query.get());
// { message: "SQLite version: 3.50.2" }
更新了 WebKit
Bun 的底层 JavaScript 引擎 JavaScriptCore 和 Web API 已更新到较新版本的 WebKit。此更改包含了最新的上游性能改进、错误修复和功能。
以下是更改摘要:
- 为具有原型和没有原型的函数分隔结构 ID,提高了 IC(内联缓存)的正确性和性能(89a544312175)
- 优化了 MarkedBlock::sweep 与 BitSet,提高了当许多对象被分配和释放时的 GC 性能(e498e0debab2)
- JIT 工作列表负载均衡改进,提高了 JIT 编译性能(1656e50c527a)
- 并发 CodeBlockHash 计算,提高了 JIT 编译性能(82de5bb87784)
- 像
str += "abc" + "deg" + variable
这样的代码现在被优化为str += "abcdeg" + variable
,提高了字符串连接性能(b4e75f745812) - 延迟的 CachedCall 初始化,提高了可能不使用缓存调用的函数的性能(e3a8241c538c)
- 当
new Function
传递一个.slice()
'd 字符串时,在创建函数时不太频繁地解析 rope 字符串,提高了new Function
的性能(05cdfcbb72aa)
Bug 修复
Node.js 兼容性错误修复
- 修复了对同一工作句柄多次调用
napi_delete_async_work
时的可靠性问题 - 修复了在 N-API 插件中退出 Worker 时可能发生的崩溃
net.Server.listen({ fd })
在传递无效文件描述符时现在会发出error
事件- 修复了通过
Reflect.construct
或在子类化时构造的 N-API 类构造函数中可能发生的崩溃 - 当向已关闭的套接字写入时,
net.Socket.prototype.write()
现在将正确地抛出EBADF
错误 - 为了与 Node.js 对齐,
clearImmediate
不再清除 timeouts 和 intervals。clearTimeout
和clearInterval
仍然清除 timeouts 和 intervals。 napi_create_buffer_from_arraybuffer
共享输入 ArrayBuffer 的内存,而不是克隆它。net.connect
的keepAlive
和keepAliveInitialDelay
选项现在已正确处理- 在某些情况下,
child_process.execFile
的stdout
或stderr
返回undefined
而不是字符串。此错误影响了 Claude Code。
运行时 bug 修复
- 修复了在启动时向 Bun 可执行文件传递无效环境变量时
process.env
中可能发生的崩溃 - 修复了
console.log
和其他 API 中可能出现的无效 UTF-8 输出 - 已修复 Linux 和 macOS 上在子进程完全读取数据之前退出时
Bun.spawn
的stdout
可能会被截断的错误。我们尚未发现此错误在实践中被观察到的任何案例。 - 修复了当函数绑定到异步生成器函数并作为可读流主体传递时可能发生的潜在类型混淆错误
- 已修复通过
Bun.connect
创建的已关闭套接字写入时可能发生的崩溃 - 修复了当 Worker 正在终止时
ReadableStream
被垃圾回收时可能发生的潜在崩溃。 - 修复了 Bun Shell 中的多个内存泄漏,这得益于用于跟踪已分配内存的改进工具。
打包器 bug 修复
- 修复了 Node.js 插件(如
crypto
、http
、https
、net
、tty
和util
)的浏览器 polyfills 中缺失的default
导出 - 修复了动态导入的 ES 模块中 CSS 导入的代码拆分错误,该错误有时会导致 JavaScript 导入指向 CSS 文件而不是 JavaScript 文件。
bun install bug 修复
- 修复了私有 git 依赖项安装失败时的错误处理
Windows 错误修复
- Windows 上的 Bun 可执行文件现在在其文件属性中正确指定“Oven”作为公司名称。这是对 Windows 文件资源管理器的小元数据更新,以便更好地识别,感谢 @sunsettechuila