《前端暴走团》,喜欢请抱走~大家好,我是团长林语冰。
今年前端愚人节可谓节目效果爆炸,先是 Vue 翻译团队官方整活,安排了一个"威优易"中文版限定彩蛋。
接着是 Bun 团队突然在朋友圈开始倒计时,后来爆料原来是 Bun 1.1 正式支持 Windows,同时版本代号为"Bundows"(我没拼错,不是 Windows)。
Bun 官网如是说,Bun 是一款专为提高性能而设计的一体化 JS 运行时和工具包,配有打包器、测试运行器和兼容 Node 的包管理器。
去年,Bun 1.0 正式发布,即第一个主版本。当时 Bun 被人诟病、美中不足的原因之一在于,Bun 能且仅能支持支持 macOS 和 Linux,Windows 操作系统成为了 Bun 的"阿喀琉斯之踵"。
但今天 Windows 支持这个缺陷也被 Bun 团队搞定了。现在压力来到了 Node 这一边,Node 惨遭 Deno 和 Bun"两面包夹芝士",汗流浃背。
自 Bun 1.0 以来已有 1700+ 次提交,我们一直在努力使 Bun 更加稳定,并更好地兼容 Node。我们修复了 1000+ 个 bug,添加了大量新功能和 API。
从 Bun 1.1 开始,Bun 正式支持 Windows!所以,今天我们一起来瞄一下 Bun 官方博客的版本升级说明吧。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 Bun 1.1。
Windows 支持
我们现在可以在 Windows 10+ 版本上运行 Bun!这对我们而言是一个巨大的里程碑,我们很高兴将 Bun 带给 Windows 开发社群。
Windows 上的 Bun 通过了我们自己的 macOS 和 Linux 上 98% 的测试套件。这意味着,从运行时、测试运行器、包管理器到打包器的所有内容,都可以在 Windows 上运行。
Windows 的 bun install
Bun 有一个内置的、兼容 npm 的包管理器,用于安装软件包。安装 Vite React App 时,bun install
在 Windows 上的运行速度比 yarn 快 18
倍,比 npm 快 30
倍。
Windows 的 bun run
我们还可以使用 bun run
运行脚本,这是比 npm run
更快的替代方案。为了使 bun run
在 Windows 上更快运行,我们设计了一种新的文件格式:.bunx
。
.bunx
文件是一个跨文件系统符号链接,能够使用 Bun 或 Node 启动脚本或可执行文件。我们决定创建它有若干原因:
- 符号链接无法确保在 Windows 奏效。
- Windows 不会读取文件顶部的 Shebangs 指令,比如
#!/usr/bin/env bun
。 - 更多细节请传送官方博客......
最终成果是,bun run
比 npm run
快 11
倍,而 bunx 也比 npx 快 11
倍。
即使您只使用 Bun 作为包管理器而不是运行时,.bunx
也可以与 Node 一起使用。这也解决了令人头大的"终止批处理作业?" 提示,这是 Windows 开发者在向正在运行的脚本发送 ctrl-c 时习惯使用的提示。
Windows 的 bun --watch
Bun 内置支持 --watch
模式。这为您提供了在更改和让这些更改影响您的代码之间的快速迭代周期。在 Windows 上,我们确保优化 control-s 和进程重载之间所需的时间。
Windows 的 Node API
我们还花时间优化 Node API,使用 Windows 上最快的系统调用。举个栗子,Bun 的 fs.readdir()
比 Windows 的 Node 快 58%。
新功能和优化
与自 Bun 1.0 以来所做的数十项新功能、API 和优化相比,Windows 支持只是冰山一角。
大型项目启动速度提高 2 倍
自 Bun 1.0 以来,我们为大于 50KB 的文件实现了内容可寻址缓存,避免重复转译相同文件的性能开销。这使得 tsc
等命令行工具的运行速度比 Bun 1.0 快 2
倍。
Bun Shell
Bun 现在是一个跨平台 shell ------ 类似于 bash,但也可以在 Windows 上运行。
JS 是世界上人气最高的脚本语言。那么,为什么运行 shell 脚本如此复杂呢?
不同的平台有不同的 shell,每个 shell 的语法规则、行为甚至命令都略有不同。举个栗子,如果您想在 Windows 上使用 cmd 运行 shell 脚本:
rm -rf
无法奏效。FOO=bar <command>
无法奏效。which
不存在。(它被替换为where
)
Bun Shell 是一个词法分析器、解析器和解释器,它实现了类似 bash 的编程语言,以及一系列核心实用程序,比如 ls
、rm
和 cat
。
Bun Shell 还可以使用 Bun.$
API 在 JS 和 TS 中运行。
js
import { $ } from 'bun'
// 标准输出管道:
await $`ls *.js`
// 字符串管道:
const text = await $`ls *.js`.text()
该语法使得在 shell 和 JS 之间传递参数、缓冲区和管道变得轻而易举。变量也会被转义,防止命令注入。
我们可以运行 bun run
使用 Bun Shell 来运行 shell 脚本。
bash
bun run my-script.sh
当使用 bun run
运行 package.json
的脚本时,Bun Shell 在 Windows 默认启用。
Bun.Semver
Bun 支持全新的 Semver
API,用于解析和排序语义化版本字符串。它与人气爆棚的 node-semver
包类似,但速度快了 20
倍。
使用 semver.order()
比较两个版本,或对版本数组排序。
js
const versions = ['1.1.0', '0.0.1', '1.0.0']
versions.sort(semver.order)
// ["0.0.1", "1.0.0", "1.1.0"]
Bun.stringWidth()
Bun 还支持全新的 stringWidth
API,用于测量终端中字符串的可见宽度。当我们想知道字符串在终端中的占用列数时,这非常有用。
js
import { stringWidth } from 'bun'
stringWidth('hello') // 5
stringWidth('👋') // 2
stringWidth('你好') // 4
import.meta.env
Bun 现在支持使用 import.meta.env
的环境变量。它是 process.env
和 Bun.env
的别名,其存在是为了与 JS 生态系统中的其他工具兼容,比如 Vite。
Node 兼容性
Bun 的目标是成为 Node 的直接替代品。Node 的兼容性仍然是 Bun 的首要任务。我们对 Bun 对 Node API 的支持进行了大量改进和修复。
兼容 Node 的 Date.parse()
Bun 使用 JSC 作为其 JS 引擎,而不是使用 V8 的 Node。Date
解析很复杂,并且不同引擎之间的行为差异很大。
举个栗子,在 Bun 1.0 中,Date
在 Node 中可以奏效,但在 Bun 中不行:
js
const date = '2020-09-21 15:19:06 +00:00'
Date.parse(date) // Bun: Date 非法
Date.parse(date) // Node: 1600701546000
为了解决这些不一致问题,我们将 Date
解析器从 V8 移植到 Bun。这意味着,Date.parse
和 new Date()
在 Bun 中的行为与在 Node 中的行为相同。
递归的 fs.readdir()
在 Bun 1.0 中,我们不支持 fs.readdir()
中的 recursive
选项。这是一个疏忽,导致许多软件包出现微妙的错误。
Bun 1.1 中,我们不仅支持 recursive
选项,而且速度比 Node 快 22
倍。
Web API
Bun 还支持 Web 标准 API,包括 fetch()
和 Response
等。这使得编同时兼容浏览器和 Bun 的代码变得轻而易举。自 Bun 1.0 以来,我们对 Web API 进行了大量改进和修复。
WebSocket
现已稳定
此前,由于诸如早期断开连接和碎片问题等协议 bug,WebSocket
被标记为实验性的。
在 Bun 1.1 中,WebSocket
现已稳定,并通过了行业标准 Autobahn 一致性测试套件。这修复了 WebSocket
客户端的数十个 bug,并使其生产使用更加可靠。
js
const ws = new WebSocket('wss://echo.websocket.org/')
ws.addEventListener('message', ({ data }) => {
console.log('收到:', data)
})
ws.addEventListener('open', () => {
ws.send('点赞关注!')
})
fetch()
使用 Brotli 压缩
您现在可以使用 fetch()
通过 br
编码发出请求。这对于向支持 Brotli 压缩的服务器发出请求非常有用。
js
const response = await fetch('https://example.com/', {
headers: {
'Accept-Encoding': 'br'
}
})
URL.canParse()
Bun 现在支持最近添加的 URL.canParse()
API。这可以检查字符串是否是有效的 URL,而不会引发错误。
js
URL.canParse('https://example.com:8080/') // true
URL.canParse('url') // false
fetch()
通过 Unix 套接字
Bun 现在支持通过 Unix 套接字发送 fetch()
请求。
js
const response = await fetch('http://localhost/info', {
unix: '/var/run/docker.sock'
})
const { ID } = await response.json()
console.log('Docker ID:', ID) // <uuid>
虽然这不是浏览器支持的 API,但它对于需要通过 Unix 套接字与服务进行通信的服务器端应用程序非常有用,比如 Docker 守护进程。
Bun 是一个兼容 npm 的包管理器
即使您不使用 Bun 作为运行时,您仍然可以使用 bun install
作为包管理器。Bun 是一个兼容 npm 的包管理器,安装速度比 npm 快 29
倍。
从 Bun 1.0 开始,我们显著提高了 bun install
的稳定性和性能。我们修复了数百个 bug,添加了新功能,并改善了整体开发体验。
修复了 1000 个 bug
自 Bun 1.0 以来,我们已经修复了 1000+ 个错误。如果您在使用 Bun 1.0 时遭遇 bug,我们鼓励您使用 Bun 1.1 重试。
在修复的数千个 bug 中,以下是您可能遭遇的某些最常见问题,现已修复:
process.nextTick()
和setImmediate()
的执行顺序与 Node 不同。- 如果存在某些前置/后置标签,
bun install
会解析为错误的版本。 - 运行
bun install
后报错Module not found
。 - 更多细节请传送官方博客......
性能优化
我们不断升级 Bun,使其更快、更高效。以下是自 Bun 1.0 以来所做的某些性能优化:
- 使用
Map
和Set
对象的expect().toEqual()
速度提高了100
倍。 setTimeout()
和setInterval()
在 Linux 上速度提高了4
倍。bunx esbuild
比npx esbuild
快50
倍。fs.readdir()
比使用recursive
选项的 Node 快40
倍。- 更多细节请传送官方博客......
坚持阅读,自律打卡,每天一次,进步一点。
《前端暴走团》,喜欢请抱走!我是团长林语冰。谢谢大家的点赞,掰掰~