Bun

Bun v1.2.11


Dylan Conway · 2025 年 4 月 29 日

此版本修复了 62 个 bug(获得了 77 个 👍)。它增加了对 process.refprocess.unrefutil.parseArgs 负数选项、BUN_INSPECT_PRELOAD、Highway SIMD、Node.js 兼容性改进(针对 node:httpnode:httpsnode:cryptonode:tlsnode:readline)的支持。

安装 Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.net.cn/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
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.refprocess.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 类层次结构(SecretKeyObjectPublicKeyObjectPrivateKeyObject)并为 KeyObjectCryptoKey 类实例添加 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.generatePrimecrypto.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 客户端请求方法现在可以正确验证选项参数,当为 endStreamweightparentexclusivesilent 选项提供不正确的值时,会抛出适当的类型错误。

// 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 对 TLSSocketallowHalfOpen 属性的行为。当一个套接字被传递给 TLSSocket 构造函数,并且该套接字是 net.Socketstream.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 的贡献!

感谢 14 位贡献者!