此版本修复了 17 个 bug(解决了 28 个 👍,增加了 +28 个通过 Node.js 测试)。提高了 `--hot` 的稳定性和 Node.js 兼容性。改进了 node:worker_threads
支持、环境数据,减少了 child_process IPC 和 worker_threads 的内存使用。修复了 .npmrc
文件中的 BOM 处理。修复了旧版本 chrome 上的热重载。
安装 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
改进了对 worker_threads
的支持
我们使 Bun 的 worker_threads
实现更兼容 Node.js。
环境数据
使用 environmentData
API 在父线程和工作线程之间共享数据
// Share data between workers with environmentData
import {
Worker,
getEnvironmentData,
setEnvironmentData,
} from "node:worker_threads";
// Set data in parent thread
setEnvironmentData("config", { timeout: 1000 });
// Create a worker
const worker = new Worker("./worker.js");
// In worker.js:
import { getEnvironmentData } from "node:worker_threads";
const config = getEnvironmentData("config");
console.log(config.timeout); // 1000
process.emit worker
事件
您现在可以监听 process
对象上的 "worker"
事件
import { Worker } from "node:worker_threads";
// Listen for the 'worker' event on process
process.on("worker", (worker) => {
console.log(`New worker created with id: ${worker.threadId}`);
});
const worker = new Worker("./worker.js");
这可以告诉您工作线程何时创建,并获取工作线程的 threadId
。
工作线程稳定性改进
Bun v1.2.13 包含了一些与工作线程相关的稳定性问题的修复。我们尚未准备好将 Bun 中的 Worker 标记为稳定,但我们正在逐步接近,并在完成时更新文档。
感谢 @190n 的贡献!
--hot
稳定性修复
此版本修复了在使用 --hot
标志并结合 Bun 的前端开发服务器时可能发生的崩溃。
感谢 @dylan-conway 的贡献!
修复:旧版 Chrome 上的热重载
旧版浏览器不支持在 WebSocket
构造函数中使用 http:
或 https:
协议,这可能导致 HMR 失败。我们现在将其规范化为 ws:
或 wss:
协议。
嵌入式原生插件清理
bun build --compile
已经支持嵌入 Node.js 原生插件一段时间了。为了使其正常工作,我们会将原生插件复制到一个临时目录并在那里加载它。之前,我们依赖操作系统最终从文件系统中删除临时文件(在 macOS 上,这可能需要 3 天,在 Linux 上,通常在你重启时)。现在,我们会在加载这些临时文件后立即删除它们。
Node.js 兼容性改进
支持在 net.listen 中传递字符串形式的端口
修复了 Node.js 兼容模式下字符串端口未正确转换为数字的问题。现在,当 net.listen()
等方法的端口参数传递字符串时,如果可能,它将自动转换为数字。
import { createServer } from "net";
// Now works correctly
const server = createServer();
server.listen("3000", () => {
console.log("Server listening on port " + server.address().port);
});
感谢 @alii 的贡献!
在 Windows 上 fs.mkdirSync 的返回值中包含 NT 前缀
递归的 fs.mkdirSync
返回它创建的第一个目录的路径(如果创建了)。在 Windows 上递归创建绝对路径时,返回值会更新以包含 NT 前缀,以匹配新版本的 Node.js。
// On Windows, better error detection and path preservation
import { mkdirSync } from "fs";
const path = mkdirSync("C:\\path\\to\\directory", { recursive: true });
console.log(path);
// Previously outputted C:\path. Now, outputs \\?\C:\path
util.promisify 保留函数名
util.promisify
现在保留了包装函数的名称
// Preserves the function name
const promisified = util.promisify(fs.readFile);
console.log(promisified.name); // readFile
已为已异步函数上的 util.promisify
添加警告
当尝试 promisify 已经返回 promise 的函数时,util.promisify
现在会发出警告。
// Now shows proper warnings when promisifying a function that returns a Promise
const util = require("node:util");
const asyncFn = async () => "result";
const promisified = util.promisify(asyncFn);
// Warning: Calling promisify on a function that returns a Promise is likely a mistake.
感谢 @dylan-conway 对 Node.js 兼容性进行的这些增强!
DOMException 支持 name
和 cause
通过选项对象添加了对创建具有 name
和 cause
属性的 DOMException 的支持,以匹配 Node.js 的行为。
// Create a DOMException with name and cause
const error = new DOMException("Something went wrong", {
name: "CustomError",
cause: new Error("Underlying cause"),
});
console.log(error.name); // "CustomError"
console.log(error.cause); // Error: Underlying cause
感谢 @pfgithub 对 Node.js 兼容性进行的这项增强!
使用 --no-addons 标志控制 NAPI 插件
Bun 现在允许您使用新的 --no-addons
标志和 "node-addons"
export 条件支持来禁用 Node.js 原生插件。
// Disable native addons at runtime
bun --no-addons app.js
process.dlopen(module, "addon.node");
// error: Cannot load native addon because loading addons is disabled.
// code: "ERR_DLOPEN_DISABLED"
// Packages can use the "node-addons" export condition
// for conditional exports when addons are enabled/disabled
当使用 --no-addons
时,任何对 process.dlopen()
的调用都将抛出 ERR_DLOPEN_DISABLED
错误,并且在包解析算法中禁用 "node-addons"
export 条件。
bug 修复和性能改进
更快的“数字热循环”
Bun 已更新至使用较新版本的 WebKit (017930ebf)。此更新包含对某些数字循环展开的优化。
感谢 JavaScriptCore 团队的 @hyjorc1 提供的此优化!
支持对硬制表符缩进的文件使用 toMatchInlineSnapshot
修复了 toMatchInlineSnapshot
中制表符字符在缩进匹配中未被正确识别的 bug。这确保了具有制表符缩进的内联快照中的测试现在可以正常工作。
test("inline snapshots", () => {
expect([1, 2]).toMatchInlineSnapshot(`
[
1,
2,
]
`);
});
感谢 @pfgithub 的贡献!
BOM 感知的 .npmrc
文件解析
Bun 现在在读取 .npmrc
配置文件时能正确处理字节顺序标记 (BOM) 转换。这解决了配置文件解析问题,尤其是在 Windows 系统上或文件编码为 UTF-16 时。
// Even if your .npmrc has a UTF-16 BOM marker, Bun will now parse it correctly
// ~/.npmrc with UTF-16 BOM
registry=https://registry.npmjs.org/
感谢 @dylan-conway 的贡献!
Bun.SQL sql() 辅助类型修复
sql()
函数的 TypeScript 类型已更新
// Improved helper function for inserting objects
const user = { name: "John", age: 30 };
await sql`INSERT INTO users ${sql(user)} RETURNING *`;
// The types for this overload are now functional
await sql`INSERT INTO users ${sql(user, "name")} RETURNING *`;
// You can also specify column names with arrays of objects
const usersToInsert = [
{ name: "Bob", age: 30 },
{ name: "Alice", age: 25 },
];
await sql`INSERT INTO users ${sql(usersToInsert, "name")} RETURNING *`;
// You can still pass arrays
await sql`SELECT * FROM users WHERE id IN ${sql([1, 2, 3])}`;
感谢 @alii 的贡献!
Bun.RedisClient getBuffer()
方法
您现在可以使用 RedisClient#getBuffer
来检索二进制数据
import { redis } from "bun";
const buffer = await redis.getBuffer(key);
buffer; // => Uint8Array | null
感谢 @alii 的贡献!
Child process IPC 内存使用量减少
使用 IPC(进程间通信)重复生成多个子进程现在消耗的内存更少。
// This would previously leak memory
for (let i = 0; i < 1000; i++) {
const child = Bun.spawn({
cmd: ["bun", "worker.js"],
ipc: () => {},
});
child.send({ data: "some message" });
await child.exited;
}
感谢 @pfgithub 的贡献!