Bun 是一款集 JavaScript 运行时、打包器、编译器和包管理器于一体的极速工具。

此次发布修复了 27 个错误(处理了 103 条反馈),修复了 Bun.serve() 性能下降 8 倍的问题,为 bun build 和 Bun 的运行时添加了新的 --conditions 标志,在 Bun 的测试运行器中添加了对 expect.assertions()expect.hasAssertions() 的支持,修复了崩溃问题并提高了与 Node.js 的兼容性。

早期版本

v1.0.29:修复了 8 个错误。Bun.stringWidth(a) 是流行 string-width 包的 ~6,756 倍速的替代插件。bunx 检查更新的频率更高。在 bun:test 中添加了 expect().toBeOneOf()。修复了影响 Prisma 的内存泄漏问题。Shell 现在支持 2>&1&> 等高级重定向。对 bunxbun install、WebSocket 客户端和 Bun Shell 进行了可靠性改进。

v1.0.28:修复了 6 个错误(处理了 26 条反馈)。修复了影响 Prisma、Astro、node:eventsnode:readlinenode:http2 的错误。修复了 Bun Shell 中涉及 stdin 重定向的错误,以及 bun:test 中与 test.eachdescribe.only 相关的错误。

v1.0.27:修复了 72 个错误(处理了 192 条反馈),Bun Shell 支持在非零退出代码时抛出错误,使用异步生成器流式传输 Response 主体,提高了 fetch()http2 客户端和 Bun.Glob 的可靠性。修复了 Linux 上 bun --watch 的性能问题。提高了与 Node.js 的兼容性。

更新内容

一、已修复:Bun.serve() 在某些情况下性能下降 8 倍

在使用 Bun.serve() 将一个数据块写入响应体的单个事件循环时,存在一个性能下降问题。此回归问题在 v1.0.4 版本中引入。

以下代码有时可以重现该问题:

Bun.serve({
  async fetch(req) {
    return new Response(
      new ReadableStream({
        type: "direct",
        async pull(controller) {
          controller.write("hello");
          await controller.end();
        },
      }),
    );
  },
});

提示:在使用 Bun 时,确保在您的 Nginx 配置中设置 proxy_http_version 1.1,HTTP KeepAlive 对性能很重要,默认情况下 Nginx 会禁用它。

二、新标志:--conditions

--conditions 标志允许您在解析来自 package.json 导出的软件包时指定要使用的条件列表。此标志受 bun build 和 Bun 运行时支持。

# Use it with bun build:
bun build --conditions="react-server" --target=bun ./app/foo/route.js
# Use it with bun's runtime:
bun --conditions="react-server" ./app/foo/route.js

Bun 已经支持 package.json"exports",此版本增加了对目标添加额外条件的支持。您还可以在 Bun.build 中以编程方式使用条件。

await Bun.build({
  conditions: ["react-server"],
  target: "bun",
  entryPoints: ["./app/foo/route.js"],
});

此 CLI 标志也由 Node.js 支持,语法相同。

感谢 @igorwessel 实现了这个功能!

三、expect.assertions()expect.hasAssertions() 现已支持

expect.assertions()expect.hasAssertions() 在 Bun 的测试运行器中受支持。

test("expect.assertions()", () => {
  expect.assertions(1);
  expect(true).toBe(true);
});

test("expect.hasAssertions()", () => {
  expect.hasAssertions();
  expect(true).toBe(true);
});

感谢 @Yash-Singh1 实现了这个功能!

四、Bun.fileURLToPath(url) 现已支持字符串

Bun.fileURLToPath(url) 现在支持字符串和 URL 对象。

// new:
Bun.fileURLToPath("file:///path/to/file.txt");

// old (still works):
Bun.fileURLToPath(new URL("file:///path/to/file.txt"));

五、Bun Shell 在错误时提供更好的堆栈跟踪

Bun Shell 在错误时提供更好的堆栈跟踪。

以前,当发生错误时,Bun Shell 不会包含完整的堆栈跟踪。这个问题已经得到修复,感谢 @zackradisic

六、已修复:Bun.serve() 中延迟请求体导致的潜在崩溃问题

​在接收到请求体后发送缓冲响应时,可能会出现崩溃问题,现已修复。

以下代码有时可以重现此问题:​​

Bun.serve({
  development: true,
  async fetch(request: Request): Promise<Response> {
    await Bun.sleep(200 + Math.random() * 100);
    const body = await (async function () {
      return await request.json();
    })();
    return new Response(JSON.stringify(body));
  },
});

此崩溃发生是因为当请求中止时,Bun 会自动拒绝正在等待的请求所消耗的 Promise,而 Bun 的代码在尝试拒绝 Promise 之前并未检查读取请求体的 Promise 是否仍在等待中。拒绝该 Promise 在内部触发了断言失败,从而导致了崩溃。

七、已修复:Bun.serve() 中带有下划线和大写名称的头部

Bun v1.0.28 增加了对在 Bun.serve() 中接收带有下划线的头部的支持。由于几个原因,Bun.serve() 会自动将所有传入的头部名称转换为小写(根据规范,HTTP 头部名称不区分大小写)。在 HTTP 服务器代码中,用于将头部名称转换为小写的部分存在错误,导致下划线在头部名称中无效,从而引发意外行为。此问题已修复。

八、已修复:textEncoder.encode() 在某些情况下的 JIT 错误

TextEncoder.prototype.encode 中的副作用配置存在错误,当在短循环中调用数千次且调用间没有分配时,可能会导致返回意外的结果。此问题已修复。

九、已修复:使用模拟函数打印错误堆栈时的崩溃问题

Bun 的模拟函数实现中存在错误,当打印包含匿名模拟函数的错误堆栈跟踪时,会导致程序崩溃。此问题已修复。

以下测试可重现崩溃问题:

test("#8794", () => {
  const target = {
    a() {
      throw new Error("a");
      return 1;
    },
    method() {
      return target.a();
    },
  };
  spyOn(target, "method");

  for (let i = 0; i < 20; i++) {
    try {
      target.method();
      expect.unreachable();
    } catch (e) {
      e.stack;
      expect(e.stack).toContain("at method ");
      expect(e.stack).toContain("at a ");
    }
    Bun.gc(false);
  }
});

十、已修复:expect(undefined).toContainKeys(a) 中的崩溃问题

expect(undefined).toContainKeys(array) 不再导致测试运行器崩溃。这是由于在 toContainKeys 匹配器中缺少对类似对象的 expect() 值的检查而导致的崩溃。

感谢 @dylan-conway 修复了这个错误。

十一、已修复:事件循环中的计时器可能导致崩溃

Bun 使用的事件循环库中存在未初始化的内存访问,在某些情况下,这可能导致在大约 16 分钟后崩溃。此错误在 Bun 的 Linux ARM64 版本上最常出现。感谢 @argosphil 修复了这个错误。

十二、Node.js 兼容性改进

此版本包含几个 Node.js 兼容性改进。

  • util/types 中的 isKeyObject 已实现
  • node:fs 中的 fdatasync 已实现
  • 当使用符号链接时 require.main 的行为类似于 Node.js
  • 已修复:napi_get_buffer_info 中的崩溃问题
  • 已修复:在 Node.js Readable 中正确发出文件结束事件
  • 已修复:node:streams 中影响 node-fetch 的缺失事件
  • 已修复:Next.js 中的 is not a function 错误
  • 已修复:node:fscp 函数在处理相对路径时的问题
  • 已修复:process.stdin 提前结束的问题

十三、Windows 支持将在 Bun v1.1.0 中推出

我们仍在努力开发 Windows 支持。虽然进展顺利,但还未准备就绪,您将很快看到支持 Windows 的稳定版本。

如果觉得我的文章对你有用,请随意赞赏