bun~bun~bun,属于你的 JS all in one

1,956 阅读7分钟

本文共 2064 字,阅读需要 5 分钟。

  • 文章全部来自手打,不添加任何 AI 辅料。如果你没了解过 bun ,没看过 bun 官网,也没关系,看完文章就可以明白它所追求的目标。
  • 我在了解、使用和思考 bun 的过程中,产生的见解和观点。

背景

最近看到 bun 的新博客,眼前一亮,如下图:

image-17.png

看到这个,我脑子一热,输出了一句卧槽,居然把空闲内存降低了 10~30%

我点进去一看,好家伙,Next.js idle memory usage 降低了 28%

image-19.png

从上图看,换句话说,相当于我服务器内存比之前节省 28% ,这省钱效果眼前一亮。举个例子。

线上环境:nextjs 使用 k8s 部署,线上 5pod

  • 优化前:每个 pod 1000M 内存
  • 优化后:每个 pod 只需要 720M

5pod 相当于节省了 1400M ,非常客观。这对于 k8s 来说,内存的节省可以直接转化为可用配额,这是赤裸裸的给公司省钱啊。

遂想写一篇文章,谈谈我对 bun 的一些想法。

这里抛出我的观点:相比于 deno ,我更看好 bun ,看完下文,即可了解我看好的理由。

bun 是什么

整体概括为以下几句话:

第一句:bun 是性能更强、架构更现代化的 JS runtime ,或者说是更好的 nodejs

第二句:bun 从诞生之日起就在第一句的基础上,不懈努力的实现 nodejs 生态的 100% 兼容

第三句:bun 一直在努力实现 JS 生态的 all in one

第一句解读——满分的性能和架构

bun 是用 zig 语言实现,zig 是一门媲美 C 的编程语言,大家对 rust 都有所了解,可以这样去理解 zig

  • zigrust 在性能上不分伯仲
  • 编程界有很多接受不了 rust 语法的人,都拥抱了 zig

所以想要实现性能更强的 js runtime ,那你的底层语言就要足够强。至此,deno 选择了 rust ,而 bun 选择了 zig

第二句解读——100%兼容nodejs

bun 的使命之一是实现 nodejs 生态的 100% 兼容,从 deno 走过的弯路看,bun 的使命是正确的,虽然难度大,但是有志者,事竟成,只要方向对,一直做这件事。总有 100% 兼容的那一天。

当我看到 bun 从诞生之时就在做这件事情,我就感觉 bun 值得期待,bun 的团队值得 nodejs 生态信任。

第三句解读——JS all in one

完全兼容 nodejs 生态,是 bun 展现给 JS 生态的诚意,而努力实现 JS 生态的 all in one 则是更好的造福整个 JS 生态。

怎么理解 all in one ,之前 antfu 分享 eslint 配置时,也提到了 all in one ,下图所示:

image.png

我们就用 antfuall in one 的解释来理解 bunjs all in one

即:化繁为简,一统江湖。

与其把核心包,工具包交给社区生态,担心未来会面临的潜在问题,nodejs 就是 "前车之鉴" 。不如 由 bun 官方一统江湖。

官方喊话:Develop, test, run, and bundle JavaScript & TypeScript projects—all with Bun

翻译版:嘿~我的前端好兄弟,写 jsts 项目,用 Bun 就对了。我提供一条龙服务,什么包管理器、单测、构建等,全都有,而且借助 zig ,性能拉满,你眼还没眨完,我包安装好了,什么,单测也跑完了?

翻译版是我翻的,纯乐呵,主要是表达 bunall in one 策略。除了内置包管理器、单测、构建。隐藏在官方喊话中的还有如下:

  • 内置 websocket 实现,还带 pub/sub 功能
  • 内置 主流数据库 driverSQLite driverPostgresSQL driver
  • 二进制打包,不依赖宿主环境,更易部署( go 的爽感)
  • jsxts 直接支持( deno 也支持,老二和老三打架,ts-node 遭殃😂)
  • monorepo 支持( pnpm workspace 那一套)
  • and so on...

bunall in onego 语言挺像,核心就是基建相关的,bun 团队负责做,当然社区也可以搞,官方也会继续做,原则上就是 Bun 团队会提供一个基于 Bunall in one 的开发环境。并且会随着 bun 的迭代,不断增强。这带给我们的收益是:

  1. 不担心这些核心库,工具被投毒、挖矿等
  2. 降低使用的心智负担
  3. 更大范围受益 bun 团队的技术能力
  4. 给生态树立规范和榜样,起到带头作用

我很赞同 bunall in one 策略,而且以现在时间点看,bun 官方在 all in one 策略上已经硕果累累了。

举例介绍

下文会选几个经典场景,介绍下 bun

qps 之王

相同环境下起 3000 端口,执行 oha http://localhost:3000 -n 500000 -H "Accept-Encoding: identity"

效果对比如下图:

node image-2.png

deno image-3.png

bun image-1.png

从图中可以得出,bun:deno:node = 4:1.7:1 ,性能可谓最强

只考虑 qps 情况下,bunnode4 倍,理论上可以节省 75% 的服务器资源。从公司角度看,这是实实在在的省钱。

当然,理论不代表实际情况,还需要结合 tps 去分析。

内置跨平台 shell

这个用着是很爽,代码如下:

import { $ } from 'bun';

// window linux mac 都是一样语法
await $`echo "Hello, world!"`;

const response = await fetch("https://baidu.com");

const data = await $`gzip < ${response}`.arrayBuffer();
console.log('gzip data:', data)

执行 bun run index.ts ,效果如下: image-14.png

快速的依赖安装

无全局缓存,从 0 开始安装依赖,bunpnpmyarn 耗费时间对比图: image-8.png

可以看到, yarn 用了 49 秒, bun13 秒, pnpm11

有全局缓存,无 node\_modulesbun、pnpm、yarn 耗费时间对比图: image-9.png 可以看到,有全局缓存的情况下,都挺快的,但是 bun 是最快的。

这里有个疑问,bun官网宣传的对比速度如下: image-10.png

提到是通过 Installing dependencies from cache 。但是我实际测试没有怎么夸张,bun 的速度并没有很突出。

强大的单测

单测速度拉满,执行如下命令

git clone git@github.com:colinhacks/zod.git 
cd zod 
bun install 
hyperfine --warmup 3 --runs 3 \ "bun test src" \ "npx vitest --config configs/vitest.config.ts" \ "npx jest -c configs/babel-jest.config.json" \ "npx jest -c configs/ts-jest.config.json" \ "npx jest -c configs/swc-jest.config.json"

单测性能对比如下图:

image-11.png

可以看到 bun 内置的 test100ms 以内就完成单测运行了,简直离谱。

该有的功能都有,而且很快

贴个官方文档图,就不在介绍了:

image-12.png

地址:bun.sh/docs/cli/te…

令人愉悦的 --hot

自带 hot reload ,如下 gif 图演示:

9999.gif

all in one 的使用体验就是安心和舒服。

bun 彩蛋部分

月提交 commit 248次

写了一个脚本对 bun 仓库的 commit 进行了分析,如下图所示:

image-4.png

2021年4月 第一次 commit 开始,到现在,平均每月提交 248 次,迭代速度拉满。

脚本就是用 bun 写的,而且用的 bun 内置的跨平台 shell 工具 $ ,涉及代码如下:

import { $ } from "bun";
async function getMonthlyCommits(repoPath: string) {
  const result = await $`git log --format="%aI"`.text();
}

这内置跨平台 shell ,用起来太爽了。

go、rust、zig的qps表现

测了下 gorustzig

go:17万 image-6.png

rust:17万 image-7.png

zig: 7万 image-15.png

测完,有点奇怪,为什么 zigqpsrustgo 差这么多,下图是开源的一个测评:

image-16.png

上图是在 linux 服务器上测的,我是在 mac 电脑上测的。估计和底层实现有关,我能想到的就是一个是没有对 mac系统 做优化,另一个是还需要调整某些参数。

这里没有细究。如果说 bun7 万,我能接受,但是 zig 也是 7 万,那就挺奇怪的。

思考

我们用惯了某某语言,某某技术后,对于新势力可能会变的迟钝,会觉得不成熟,不稳定,没必要。但是换个角度思考,我们用惯的这些,在没成熟,不稳定时,也有很多人会觉得没必要,我们要用包容和期待的技术视野去关注、了解和分析新语言、新技术、新风向的发展,这样你更容易成为第一批吃螃蟹的人。