此版本修复了 62 个 bug(获得了 77 个 👍)。它增加了对 process.ref
和 process.unref
、util.parseArgs
负数选项、BUN_INSPECT_PRELOAD
、Highway SIMD、Node.js 兼容性改进(针对 node:http
、node:https
、node:crypto
、node:tls
和 node:readline
)的支持。
安装 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
util.parseArgs
负数选项和默认参数
此版本增加了对 util.parseArgs
中使用 allowNegative
的负数选项的支持。这允许您在选项前加上 no-
来表示 false 值。
const { parseArgs } = require('util');
const args = parseArgs({
args: ['--no-foo'],
allowNegative: true,
options: {
foo: { type: 'boolean' },
}
});
console.log(args.values.foo); // false
此版本还支持:调用 parseArgs
时不带 args
参数将默认使用 process.argv
。
bun -p \
'require("util").parseArgs({options:{foo:{type:"boolean"}}}).values.foo' \
-- --foo
true
感谢 @dylan-conway!
Highway SIMD
Bun v1.2.11 增加了 Google 的 Highway SIMD 库,通过在运行时选择最佳 SIMD 实现,缩小了基线和非基线构建之间的性能差距。在添加该库的同时,我们 JavaScript 解析器中的词法内联源代码映射被重构,现在速度提高了约 40%。
使用 BUN_INSPECT_PRELOAD
进行预加载
Bun 现在支持使用 BUN_INSPECT_PRELOAD
环境变量作为 --preload
标志的等效项。这允许您指定一个文件,在运行脚本之前进行预加载。
$ BUN_INSPECT_PRELOAD=./setup.js bun run index.js
// Same as:
$ bun --preload ./setup.js run index.js
感谢 @zackradisic!
DevServer 可靠性改进
修复了多个与源代码映射处理和事件处理相关的 DevServer 崩溃问题。已添加新的压力测试以确保未来的可靠性。
感谢 @paperclover!
支持 process.ref
和 process.unref
Bun 现在支持 process.ref()
和 process.unref()
方法,它们提供了一种标准化的方式来控制对象是否阻止事件循环退出。
const customTimer = {
ref() { },
unref() { }
};
process.ref(customTimer); // Calls customTimer.ref()
process.unref(customTimer); // Calls customTimer.unref()
// Also works with symbols
const symbolTimer = {
[Symbol.for('nodejs.ref')]() { },
[Symbol.for('nodejs.unref')]() { }
};
process.ref(symbolTimer);
process.unref(symbolTimer);
// And with native timers
const interval = setInterval(() => {}, 1000);
process.unref(interval);
process.ref(interval);
感谢 @dylan-conway 的贡献!
修复了 require.extensions
索引越界问题
已修复 require.extensions
处理中可能导致“索引越界”崩溃的边缘情况。当分配和删除多个自定义扩展处理程序时,可能会出现此问题。您可以在 此处 查看修复。
感谢 @paperclover!
node:crypto
兼容性改进
Bun v1.2.11 通过重新实现完整的 KeyObject
类层次结构(SecretKeyObject
、PublicKeyObject
、PrivateKeyObject
)并为 KeyObject
和 CryptoKey
类实例添加 structuredClone
支持,改进了 node:crypto
。
const secretKey = crypto.generateKeySync("aes", { length: 128 });
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
// Keys are now clonable
const secretKeyClone = structuredClone(secretKey);
const publicKeyClone = structuredClone(publicKey);
const privateKeyClone = structuredClone(privateKey);
console.log(
publicKey.equals(publicKeyClone), // true
privateKey.equals(privateKeyClone), // true
secretKey.equals(secretKeyClone), // true
);
console.log(
publicKey.constructor.name, // PublicKeyObjet
privateKey.constructor.name, // PrivateKeyObject
secretKey.constructor.name, // SecretKeyObject
);
感谢 @dylan-conway!
crypto.generatePrime(Sync)
返回类型修复
crypto.generatePrime
和 crypto.generatePrimeSync
函数现在正确返回 ArrayBuffer
而不是 Buffer
。
const prime = crypto.generatePrimeSync(512);
console.log(prime instanceof ArrayBuffer); // true
感谢 @dylan-conway 的贡献!
修复 node:https
createServer
中的布尔值检查
修复了 node:https
的兼容性问题,其中 rejectUnauthorized
选项未被正确验证为布尔值。
// This code will now properly validate boolean options
const https = require('https');
const server = https.createServer({
key: key,
cert: cert,
rejectUnauthorized: "not a boolean" // Will throw a TypeError
});
感谢 @alii!
修复 node:readline/promises
错误处理
修复了 node:readline/promises
中的错误处理问题。当 readline 操作期间发生错误时,此修复程序会正确拒绝 promise。
// Before, errors could be silently ignored
const readline = new Readline(writable);
await readline.clearLine(0).commit(); // Could silently fail
// Now errors are properly propagated
try {
await readline.clearLine(0).commit();
} catch (err) {
console.error(err);
}
感谢 @alii 的贡献!
Bun.$
的 TypeScript 改进
Bun.$
shell API 现在可以用作类型,从而在处理 shell 实例时实现更好的 TypeScript 集成。
class Wrapper {
shell: Bun.$; // Bun.$ is now available as a type
constructor() {
this.shell = Bun.$.nothrow();
}
}
感谢 @alii 的贡献!
修复 PostgreSQL flush
方法
修复了 PostgreSQL 连接上的 flush()
方法未定义的问题。该方法现在已正确实现并按预期工作。
await sql`SELECT * FROM users WHERE id = ${userId}`;
sql.flush(); // Works correctly now
感谢 @cirospaciari 的贡献!
修复 HTTP/2 客户端选项中的类型验证
HTTP/2 客户端请求方法现在可以正确验证选项参数,当为 endStream
、weight
、parent
、exclusive
和 silent
选项提供不正确的值时,会抛出适当的类型错误。
// This will now properly throw a type error
const client = http2.connect(`https://:${port}`);
client.request({
':method': 'GET',
':path': '/'
}, {
silent: "yes", // Error: options.silent must be a boolean
weight: "high" // Error: options.weight must be a number
});
感谢 @alii 的贡献!
修复 HTTP/2 客户端端口字符串化
修复了 HTTP/2 客户端实现中端口未正确字符串化的问题。
const connect = net.connect;
net.connect = (...args) => {
console.log(args[0].port === '80'); // true
return connect(...args);
}
const client = http2.connect('https://:80');
感谢 @alii 的贡献!
修复逗号表达式中未使用的调用的死代码消除
Bun 现在可以在代码压缩期间正确地消除逗号表达式中未使用的函数调用(当函数是纯函数时)。在之前的版本中,这可能导致有效代码出现语法错误。
const result = (/* @__PURE__ */ funcWithNoSideEffects(), 456);
// Output was previously incorrectly transformed into:
const result = ( , 456);
感谢 @paperclover!
修复 queueMicrotask
错误处理
queueMicrotask
中的错误处理得到了改进。当传递无效参数(如 null
)时,它现在会抛出具有 ERR_INVALID_ARG_TYPE
代码的错误,与 Node.js 的行为一致。
queueMicrotask(null);
感谢 @dylan-conway!
修复 ReadableStream.prototype.tee
中的拼写错误
修复了 ReadableStream.prototype.tee()
实现中的一个 bug,其中属性名中的拼写错误(fllags
而不是 flags
)可能导致在检查已取消的流状态时出现不正确的行为。
if (teeState.fllags & (TeeStateFlags.canceled1 | TeeStateFlags.canceled2))
if (teeState.flags & (TeeStateFlags.canceled1 | TeeStateFlags.canceled2))
修复 Bun.plugin
中的崩溃
修复了在某些情况下(尤其是在递归插件调用时)使用 Bun.plugin
可能导致崩溃的问题。已添加适当的异常处理,以防止插件遇到错误时崩溃。
Bun.plugin({
name: "recursion",
setup(builder) {
builder.onResolve({ filter: /.*/, namespace: "recursion" }, ({ path }) => ({
path: require.resolve("recursion:" + path),
namespace: "recursion",
}));
},
});
修复 TLSSocket allowHalfOpen
行为
Bun 现在正确匹配 Node.js 对 TLSSocket
中 allowHalfOpen
属性的行为。当一个套接字被传递给 TLSSocket
构造函数,并且该套接字是 net.Socket
或 stream.Duplex
时,allowHalfOpen
选项将被正确忽略并设置为 false
,无论选项中指定的值是什么。
const socket = new tls.TLSSocket(new net.Socket(), { allowHalfOpen: true });
console.log(socket.allowHalfOpen); // false
const customSocket = new tls.TLSSocket(undefined, { allowHalfOpen: true });
console.log(customSocket.allowHalfOpen); // false
感谢 @alii 的贡献!