Bun 0.6.4 正式发布,你学会了吗?

开发 前端
最新版本的 Bun 现在有一个内置的 JavaScript 和 TypeScript 捆绑器和简化器,可以用它来捆绑前端应用程序或将你的代码捆绑成一个独立的可执行文件。

大家好,我是Echa。

好消息,2023年5月26号Bun 官方对外发布 Bun 0.6.4 版本,距离上一次Bun 0.6.0版本(2023年5月16号),短短只有10天时间。据 Bun官方的说法是,Bun 0.6.0 版本是迄今为止 Bun 最大的一次更新版本。接下来小编带着大家细聊Bun 最近更新了哪些内容。

全文大纲

  1. Bun 前言
  2. 全新的Bun 官网介绍
  3. Bun最新版更新重点

Bun 前言

Bun Github 41.6k

刚开源不到一个月就获得了 26k多star!现在已经41.6k star。看起来马上就会成为 Node.js 和 Deno 的一大竞争对手了!和传统的 Node.js 这种传统的 javaScript 运行时不同,Bun.js 直接内置了打包器、转译器、任务运行器和 npm 客户端,这意味着你不再需要
Webpack/Rollup/esbuild/Snowpack/Parcel/Rome/swc/babel 就可以直接运行 TypeScript、JSX!

另外,Bun.js 原生支持了数百个 Node.js 和 Web API,包括约 90% 的 Node-API 函数(fs、path、Buffer 等)。

Bun.js 的目标是可以在浏览器之外的其他地方运行世界上大多数 JavaScript,为你未来的基础架构带来性能和复杂性的增强,并通过更好、更简单的工具提高开发者的生产力!

在2022 年 JavaScript 明星项目中Bun排名第一

2022 年 JavaScript 明星项目中Bun排名第一

Bun 是 一个专注性能与开发者体验的全新 JavaScript 运行时。它的流行程度伴随着在今年夏天发布的第一个 Beta 版而爆炸性增长:仅一个月内,就在 GitHub 上获得了超过两万颗星星。自从我们在 Best of JS 开始统计项目以来,我们还从未见过这样的爆炸。

那么,是什么让 Bun 与众不同呢?与两年前的总冠军 Deno 一样,它也为 TypeScript 提供了一流的支持。

但 Bun 不仅仅是一个运行时。它也是:

  • 一个包管理器 (类似 Yarn、 NPM、 PNPM)
  • 一个构建工具 (类似 Webpack、 ESBuild、 Parcel)
  • 一个测试运行器
  • ... 以及很多其他东西!

所以 Bun 可以通过读取你的 package.json 来安装依赖项。Bun 还可以运行你的脚本。不管它做什么都比其他工具更快。

Bun 在 JavaScript 生态系统的许多方面都有新的尝试,其中的重点是性能。

它优先支持标准的 Web API,如 Fetch。它也支持许多 Node.js APIs,使其能与大多数 NPM 包兼容。

它可能还没到 “能用于生产” 的阶段(缺乏 Windows 支持),但它依旧是一个非常有前途的工具。与 Deno 相比,它的生态系统相当新,但它已经有一个名为 Elysia 的网络框架,其声称是最快的 HTTP 框架。

Bun 作者 Jarred Sumner

Bun 最不可思议的是,它的创造者 Jarred Sumner 用的是一种名为 Zig 的低级语言从零开始实现了所有这些功能。

全新的Bun 官网介绍

官网:https://bun.sh/

Github:https://github.com/oven-sh/bun

今天的主角,Bun.js(下称 Bun),新一代的 All-In-One 的 JavaScript 运行时,Node.js(下称 Node) 和 Deno 的挑战者。

Bun是一个全新的JavaScript运行库,从头开始构建,为现代JavaScript生态系统服务,有三个主要设计目标:

  • 快速启动。在边缘计算环境中,减少冷启动时间至关重要。
  • 快速运行性能。Bun扩展了JavaScriptCore,这是为Safari构建的注重性能的JS引擎。
  • 粘性DX。Bun是一个用于构建JavaScript应用程序的完整工具包,包括bundler、transpiler和包管理器。

Bun是Node.js的替代品。使用它可以在本地计算机、服务器或边缘运行当前的JavaScript&TypeScript应用程序或脚本。Bun本机实现了数百个Node.js和Web API,包括约90%的Node-API函数(本机模块)、fs、path、Buffer等。

Bun的目标是在浏览器之外运行世界上大多数的JavaScript,为您未来的基础设施带来性能和复杂性增强,并通过更好、更简单的工具提高开发人员的生产力。

Bun 性能表现如何?

服务端渲染:每秒处理 HTTP 请求数对比


每秒处理 HTTP 请求数对比

每秒发送的邮件数对比:

每秒发送的邮件数对比

加载一个巨大的 sqlite 表:每秒平均查询次数对比

每秒平均查询次数对比

Bun bundler简介

一个快速的JavaScript打包程序。用于web浏览器的捆绑、树摇和迷你ES模块、CommonJS、TypeScript和JSX。

为啥这么快?

和 Node.js、Deno 不同,Bun.js 并没有基于 V8 引擎,它直接选择了 JavaScriptCore 引擎,它的执行速度往往要比 V8 等更传统引擎要快。

另外,Bun.js 是用一种具有手动内存管理的低级编程语言 ZIG 编写的,对内存的低级控制、没有隐藏的控制流可能就是它性能非常好的秘诀。

Bun.js 的大部分内容都是完全从零开始编写的,包括 JSX/TypeScript 转译器、npm 客户端、打包器、SQLite 客户端、HTTP 客户端、WebSocket 客户端等等。

有哪些能力?

  • Web API:对 fetch、WebSocket、 ReadableStream 等 API 都提供了内置支持
  • Node.js 模块:Bun 实现了 Node.js 的模块解析算法,同时支持 ESM 和 CommonJS,但 Bun 内部使用 ESM。
  • 支持转译大量文件类型,你可以直接运行 TypeScript、JSX,甚至支持各种 tsconfig.json 中的配置。

Bun最新版更新重点

Bun 0.6.0 版本

根据官方说法,Bun 0.6.0 版本是迄今为止 Bun 最大的一个更新版本。

最新版本的 Bun 现在有一个内置的 JavaScript 和 TypeScript 捆绑器和简化器,可以用它来捆绑前端应用程序或将你的代码捆绑成一个独立的可执行文件。

Bun 0.6.0 也一直在忙着提高性能和修复 bug:writeFile() 在 Linux 上的速度提高了 20%、对 Node.js 兼容性和 Web API 兼容性进行了大量的 bug 修复、支持 TypeScript 5.0 语法,并对 bun install 进行了各种修复。

新的 JavaScript bundler & minifier

这个版本的重点是 Bun 的新 JavaScript Bundler(捆绑器),但捆绑器只是一个更大项目的开始。在接下来的几个月里,Bun 将发布 Bun.App—— 一个 "超级 API",将 Bun 的 native-speed 捆绑器、HTTP 服务器和文件系统路由缝合成一个整体。

可以使用 bun build CLI 命令或新的 Bun.build() JavaScript API 来使用。

JavaScript

Bun.build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./build",
  minify: true,
  // ...
});

CLI

bun build ./src/index.tsx --outdir ./build --minify

独立的可执行文件

现在你可以用 bun build 来创建独立的可执行文件。

bun build --compile ./foo.ts

这让你可以将你的应用程序作为一个可执行文件发布,而不需要用户安装 Bun。

你也可以将其缩小,以提高大型应用程序的启动性能:

bun build --minify --compile ./three.ts
  [32ms]  minify  -123 KB (estimate)
  [50ms]  bundle  456 modules
 [107ms] compile  three

这是由 Bun 的新 JavaScript 捆绑器和简化器提供的。

import.meta.main

现在你可以使用 import.meta.main 来检查当前文件是否是启动 Bun 的入口点。这对 CLI 很有用,可以确定当前文件是否是启动应用程序的。

例如,如果你有一个名为 index.ts 的文件:

index.ts

console.log(import.meta.main);

然后你运行它:

$ bun ./index.ts
true

但如果你导入它:

import "./index.ts";

并运行它:

$ bun ./other.ts
false

对bun test的改进

  • bun test 现在报告运行测试的时间
  • describe.skip 已经实现
  • 实现了 expect().toBeEven() 和 expect().toBeOdd()

在 Linux 上实现更快的fs.writeFile

fs.writeFile 在 Linux 上处理大文件的速度提高了 20%

转译器改进

这个版本还引入了许多对转译器的改进。以下是其中的一些亮点:

  • 解析器支持 TypeScript 5.0。
  • 解析器支持导入属性。
  • 一些 npm 包出现了 ReferenceError: Cannot access uninitialized variable 的错误,这是由于 Bun 的转译器中存在循环导入的错误。这一点已被修复。
  • 支持 // @jsx// @jsxImportSource 和 // @jsxFragment 注释
  • ……

Bun Bundler

Bun的快速原生bundler现在处于测试阶段。它可以通过bun-build CLI命令或新的bun.build()JavaScript API使用。

使用bundler通过内置Bun.build()函数或Bun-build CLI命令构建前端应用程序。

Bun.build({
  entrypoints: ['./src/index.tsx'],
  outdir: './build',
  minify: true,
  // additional config
});

降低JavaScript的复杂性

JavaScript最初是表单字段的自动填充,如今它为向太空发射火箭的仪器提供动力。

不出所料,JavaScript生态系统的复杂性激增。如何运行TypeScript文件?您如何构建/捆绑您的代码以用于生产?该软件包适用于ESM吗?如何加载仅本地配置?我需要安装对等依赖项吗?如何使源地图正常工作?

复杂性需要时间,通常需要将工具粘在一起或等待完成。安装npm程序包花费的时间太长。运行测试应该需要几秒钟(或更短)。为什么在2023年部署软件需要几分钟,而在2003年将文件上传到FTP服务器需要几毫秒?

多年来,我一直对JavaScript的速度感到沮丧。当从保存文件到测试更改的迭代周期长到足以本能地检查Hacker News时,就说明出了问题。

这种复杂性是有充分理由的。捆绑包和迷你包使网站加载更快。TypeScript的编辑器内交互式文档使开发人员的工作效率更高。类型安全有助于在错误发送给用户之前发现错误。作为版本化包的依赖项通常比复制文件更容易维护。

当“一件事”被拆分在这么多孤立的工具之间时,Unix的“做好一件事情”哲学就崩溃了。

toLocaleString()速度提高79倍

多亏了@Constellation,数字上的toLocaleString()速度提高了79倍。

toLocaleString将数字转换为当前区域设置预期读取字符串的方式。

这对代码的影响如下:

const myNumber = 123;

myNumber.toLocaleString();

JSON.parse快20%,JSON.stringify快15%

多亏了@Constellation,在没有许多嵌套对象的对象上,JSON.parse在对象上的速度快了20%,而在相同的场景中,JSON.stringify的速度快15%。

之前:

之后:

Node.js,用于比较:

Object.assign 用空对象分配会更快

多亏了@Constellation,Object.assign()和空对象作为第二个参数,速度快了2倍。

function test(options) {
  var options = Object.assign({ defaultParam: 32 }, options);
  return options;
}

// empty object as the 2nd arguemnt to object assign
test({});

返回参数的速度快2倍

也多亏了@Constellation,在函数中返回参数的速度提高了2倍

function test(a, b, c) {
  return arguments;
}

for (var i = 0; i < 1e6; ++i) test(0, 1, 2);

涉及模板字符串的小型化程序错误

由于bun的解析器中模板文本中包含字符串的逻辑不正确,这样的代码有时会产生不正确的字符串:

const foo = ".*";
const regex1 = new RegExp(foo); // Invalid regular expression: unmatched parentheses
const regex2 = new RegExp(`(${foo})`);

Bun 0.6.3 版本

官方我们发布了对node:vm的支持、对node:tls和node:http的改进,修复了对socket.io和mongodb的支持,对bun-test的改进,引入了test.todo()、测试超时和更好的预加载,以及对bun的bundler的许多修复。

介绍节点:vm

Bun现在支持内置的node:vm模块。它可以用来执行代码,类似于eval(),只是对代码执行的globalThis JavaScript上下文有更多的控制。

import { runInContext } from "node:vm";

let context = {
  foo: "bar",
  baz: 123,
};

runInContext(`foo = "fizz"; delete baz;`, context);

console.log(context.foo); // "fizz"
console.log(context.baz); // undefined

您还可以使用runInNewContext在单独的JavaScript上下文中运行代码。

import { runInNewContext } from "node:vm";

runInNewContext(`globalThis.fetch = undefined;`);

console.log(globalThis.fetch); // [Function fetch]

修复了node:tls和node:http

官方我们已经修复了许多使用TLS和HTTP的代码,例如TLS握手,因此您现在可以在Bun中使用socket.io和mongodb身份验证。

bun测试的改进

现在,您可以使用test.todo()标记以后要实现的测试。

expect().toBeCloseTo()

import { test, expect } from "bun:test";

test("toBeCloseTo()", () => {
  expect(3 + 0.14).toBeCloseTo(3.14);
  expect(3.14).toBeCloseTo(Math.PI, 2);
});

Test timeouts

import { test } from "bun:test";

test("i took too long", async () => {
  await Bun.sleep(100);
}, 50); // the last argument is a timeout in milliseconds


Hook support with --preload

现在可以使用带有--preload标志的beforeAll、beforeEach、afterEach和afterAll。

这使您可以在所有文件之前和之后运行代码,而不仅仅是当前文件。这对于在运行测试之前需要初始化的库非常有用。

import { test, beforeAll, beforeEach, afterEach, afterAll } from "bun:test";

beforeEach(() => {
  console.log("This runs before each test in every file");
});

Fixes to pretty-printing

官方我们还修复了一个错误,该错误会导致像这样的代码在测试运行程序中将值打印为未定义值。

import { test, expect } from "bun:test";

test("wat", () => {
  const left = {};
  const right = {};
  for (let i = 0; i < 2; i++) {
    left[i] = i + 1;
    right[i] = i + 2;
  }
  expect(left).toBe(right);
});


Fixes tobun build

  • 当启用了具有多个入口点的--minify时,在使用Bun.js作为捆绑程序时突出显示的崩溃已修复。当合并相邻的顶级变量声明时,这是一个竞争条件。
  • 已修复导致资产复制到错误输出路径的错误。
  • 已修复一个涉及模板文字合并错误的缩小程序错误。
  • 生成源映射时可能出现的竞争条件已修复。
  • 一个允许生成的变量名以数字开头的错误已经修复。
  • 保存到磁盘后创建BuildArtifact对象时可能发生的崩溃已修复。
  • 日志中的内存泄漏已修复。
  • 改进了在为浏览器构建时使用内置Node.js建议将--target选项设置为Node或bun时的错误消息。

fetch()memory leak

在fetch()中发现的两个内存泄漏已修复。

回调创建了两个对Promise<Response>对象的强保留引用,这防止了它被垃圾收集。

输入验证逻辑可能会创建一个强保留的Promise<Response>并立即丢弃它,而不会释放强引用。这防止了Promise<Response>被垃圾收集。

这很尴尬,我们已经提高了内存泄漏测试的测试覆盖率,以确保这种情况不会再次发生。以下是内存泄漏的图表,由@dimka3553提供:

Bun 0.6.4版本

官方我们发布了bun测试的改进、Node.js兼容性错误修复、console.log()改进、可修改时区、require.cache支持、bundler错误修复等。

bun测试速度提高80%

官方我们已经使bun测试速度提高了80%,尤其是在有很多小测试文件的情况下。

Bun过度安排垃圾收集器在每个文件上同步运行。它已经在堆大小发生变化时调度GC,所以这是不必要的。这导致内存使用量增长了9%左右,这很好,因为与其他具有相同代码的测试运行程序相比,Bun使用的内存减少了2-4倍。

bun测试读取.env.test和.env.test.local

  • NODE_ENV=测试现在已正确设置。
  • 环境变量可以从.env.test和.env.test.local文件中读取。

bun test timeouts

现在,您可以通过传递--timeout或将第三个可选数字参数传递给test()来为测试设置超时。

import { test } from "bun:test";

test("i took too long", async () => {
  await Bun.sleep(100);

  // the last argument is a timeout in milliseconds
}, 50);

expect().toHaveLength() and expect().toBeEmpty()

现在支持expect().toHaveLength()和expect(。toBeEmpty()。这些测试匹配器可用于Blob、Buffer、File、Headers、Map、Set、String、TypedArray和类数组对象。

mport { expect, test } from "bun:test";

test("expect().toHaveLength()", () => {
  expect([1, 2, 3]).toHaveLength(3);
  expect([1, 2, 3]).not.toHaveLength(2);

  // Works on Blob, Buffer, File, Headers, Map, Set, String, TypedArray, and Array-like objects, or anything with a .length property
  expect(new Headers({ Origin: "https://bun.sh" })).toHaveLength(1);
});

test("expect().toBeEmpty()", () => {
  expect([]).toBeEmpty();
  expect([1]).not.toBeEmpty();

  // Works on Bun.file() too
  expect(Bun.file(import.meta.path)).not.toBeEmpty();
});

最后

一台电脑,一个键盘,尽情挥洒智慧的人生;几行数字,几个字母,认真编写生活的美好;

一 个灵感,一段程序,推动科技进步,促进社会发展。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-08-01 12:51:18

WebGPT机器学习模型

2024-01-02 12:05:26

Java并发编程

2024-02-04 00:00:00

Effect数据组件

2024-01-19 08:25:38

死锁Java通信

2023-07-26 13:11:21

ChatGPT平台工具

2023-01-10 08:43:15

定义DDD架构

2022-06-16 07:50:35

数据结构链表

2024-03-06 08:28:16

设计模式Java

2023-05-05 06:54:07

MySQL数据查询

2023-10-06 14:49:21

SentinelHystrixtimeout

2024-02-02 11:03:11

React数据Ref

2023-06-26 13:08:52

GraphQL服务数据

2022-12-06 07:53:33

MySQL索引B+树

2022-07-13 08:16:49

RocketMQRPC日志

2023-07-30 22:29:51

BDDMockitoAssert测试

2023-08-26 21:34:28

Spring源码自定义

2023-03-26 22:31:29

2023-01-31 08:02:18

2024-07-31 08:39:45

Git命令暂存区

2022-07-08 09:27:48

CSSIFC模型
点赞
收藏

51CTO技术栈公众号