咱们好,这里是咱们的林语冰。

Bun 是一个新型 JS 运转时,去年就供给了 Windows 试验版。据最新音讯,今年最新的 Windows 安稳版行将发布,敬请期待。

本期同享的是 —— Bun 是 Node 和 Deno 的 JS 运转时竞品。在本文中,咱们会科普 Bun 1.0,以及它或许诱使咱们抛弃当前最爱的 Node 的若干原因。

Bun 的 Windows 安稳版行将发布,重温 Bun 运转时

免责声明

本文属所以语冰的直男翻译了属所以,略有删改,仅供粉丝参考。英文原味版请传送 An Introduction to the Bun JavaScript Runtime

运转时简史:Bun vs Node vs Deno

“Node 之父” R.D. 于 2009 年发布了 Node。Node 并不是首个服务端 JS 运转时,但 Node 找到了“流量暗码”。Node 20 于 2023 年发布,它拥有最大的开发生态系统,拥有 320 万个模块,依据 npmjs.com 的数据,其周下载量高达 5_000 亿次。

2020 年,“Node 之父”发布了 Deno,意思是“noDe”的重新组合,旨在完成 JS 现代化开发,并处理 Node 安全性、API 兼容性、东西和模块办理方面的留传问题。尽管 Deno 尚未将 Node 拉下神坛,但社区反响仍是元气满满。

2022 年,J.S. 在开发 Next 项目时对 Node 的速度感到头大,所以发布了 Bun。

Bun 运用 JSC(JavaScriptCore)引擎,JSC 为苹果 Safari 等 WebKit 浏览器供给支撑,而不是 Node、Deno 和谷歌 Chrome 中运用的 V8 引擎。

Bun 运转时重视功用和开发体会,其目的是消除缓慢和杂乱性,一起又不抛弃 JS 的一切长处。

Bun 的开展速度比 Node 更快 —— 它有必要尽量保持与现有 JS 和 npm 生态系统的向后兼容。

与 Deno 相同,Bun 原生支撑 JS/TS,无需第三方转译器或装备。

Bun 正在成为 Node、Deno、无服务器运转时(serverless runtimes)、构建和测验东西的直接代替品。Bun 能够代替 npm、TS 编译器、nodemon、Webpack、Babel 和 Jest,供给完好的功用全家桶 —— 用于在单一渠道上开发 App 的齐备东西箱。

Bun 开始的运转时是安稳的,但由于近 300 名开发者的无私奉献,Bun 1.0 版别于 2023 年 9 月发布。这将不可避免地招引更多开发者迁移到 Bun,在这里它们能够享用下面描绘的优点。

Bun 的由来

“Bun”这个姓名的由来尚不清楚,而且标志也杯水车薪!Bun 或许与食物、毛烘烘的小兔子、“bundle”(打包器)有关,或者或许是一个简略、令人难忘的称号,而且 Bun.sh 域名可用。

Bun 的 Windows 安稳版行将发布,重温 Bun 运转时

Bun 的优势

Node 和 Deno 运用谷歌 Chrome 的 V8 JS 引擎。Bun 挑选了 JSC 引擎,该引擎为苹果 Safari 等 WebKit 浏览器供给支撑。Bun 自身是用 Zig 编写的,Zig 是一种低级编程言语,具有手动内存办理和原生线程来处理并发。结果是轻量级运转时具有更小的内存占用、更快的发动时刻,而且在某些基准测验条件下功用比 Node 和 Deno 快 4 倍。

与 Deno 相同,Bun 原生支撑 JS/TS,无需第三方转译器或装备。Bun 还支撑 .jsx/.tsx 文件,这会将相似 HTML 的标记转换为原生 JS。Bun 供给了对运转 WebAssembly 编译的 .wasm 文件的试验性支撑。

Bun 支撑 Node 的 package.jsonnpm 等效指令,以及 Bunx — 一个相似 npx 的选项,可在单个指令中主动装置和运转包。举个栗子:

bunx cowsay "Hello, world!"

bun init 脚手架经过与 npm init 相同的方式构建空项目,但咱们也能够运用 bun create <template> <destination> 模板化新项目,其间 <template> 是官方包、Github 存储库或本地包。举个栗子,要创立一个新的 Next 项目:

bun create next ./myapp

Bun 包含一个打包器,用于将一切依靠导入到单个文件中,且能够针对 Bun、Node 和客户端 JS。这削减了运用 esbuild 或 Rollup 等东西的需求:

bun build ./index.ts —outdir ./out

大多数指令行界面选项都能够经过 JS API 取得,因而无需专用的使命运转程序就能够创立杂乱的构建脚本。这是与上面指令相同的构建:

await Bun.build({
  entrypoints: ['./index.ts'],
  outdir: './out'
})

项目 .env 文件中包含的环境变量会主动加载和解析,使其在 Bun App 中可用,因而无需运用 dotenv 等包。

除了 Bun 自己用于网络、文件访问、子进程等的 Bun API 之外,Bun 还支撑:

  • Web API,比方 fetchJSONsetTimeout 和事件等。
  • 兼容 Node API,比方 consolehttppath 等,以及大局变量,包含 __dirname__filename 。Bun 声称 90% 最常用的 API 都已完全完成,尽管咱们应该仔细检查特定于自己项目的 API。

装置 Bun

Bun 能够经过 Node 包办理器装置:

npm install -g bun

装置后,咱们能够运用以下指令晋级 Bun:

bun upgrade

或者能够经过删去 ~/.bun 二进制文件和缓存目录来卸载 Bun:

rm -rf ~/.bun

然后更新 shell 装备文件(.bashrc 或相似文件),以从 $PATH 变量中删去 ~/.bun/bin 引用。

运用 Bun

如果咱们从项目起步就运用 Bun,那么 Bun 是牢靠的。速度比 Node 更快,但除非咱们的 App 正在履行特定的密集型使命,比方繁重的 SQLite 处理或 WebSocket 音讯传递,不然咱们不太或许感知到功用的明显提升。

Node 的兼容性关于更言简意赅的项目优点多多,我成功地运用 bun start 发动了某些脚本,且无需进行任何更改。更杂乱的 App 或许“试试就去世”,并在 node_modules 层次结构深处生成了含糊的过错音讯。

Bun vs Deno vs Node

Deno 处理了 Node 的许多缺点,但开发者不一定觉得有必要切换到 Deno:

  • Deno 不支撑 Node 的第三方模块。
  • 从 Node 迁移到 Deno 需求学习本钱。
  • 尽管 Deno 供给了更好的开发体会,但 Node 也差强人意。

Deno 现在添加了 Node 兼容性选项。这是让开发者过渡到 Deno 的最简略计划,但与此一起,Node 采用了 Deno 的某些功用,包含 ESM 模块、原生测验运转器和 —watch 模式。

Bun 采取了不同的计划,旨在成为一个比肩 Deno、与 Node 兼容的快速引擎。理想很丰满,但还没有完成:

  • 功用爆棚,但很少有开发者抱怨 Node 的速度。
  • 兼容性很好,但在不同的 JS 引擎中支撑一切 Node 模块是一个挑战。JSC 能否以更少的出资跟上 V8 的开展?
  • Bun 有潜力取代咱们的东西套件,但它尚未供给 Deno 中的全部功用。

Bun 与 Node 的兼容性

Node 兼容性一般合适言简意赅的项目。咱们也许能够运用 bun start 而不是 npm start 来发动某些脚本,而无需进行任何更改。

Bun 支撑:

  • 内置 Node 模块和 API,比方 fspathconsole 等等
  • 大局变量和对象,比方 __dirnameprocess
  • Node 模块解析算法来定位 node_modules 中的文件

Bun 1.0 声称能够运转“简直任何 Node App”。我信你个大头鬼;杂乱的 App 或许遭遇滑铁卢,并在第三方模块深处生成含糊的过错音讯。

ESM 和 CJS 模块兼容性

Bun 支撑具有顶层 await 的 ESM 和 CJS 模块系统。ESM 花了几年时刻才进入 Node,而且生态系统依然由 CJS 主导。运用 Bun,不需求特定的文件扩展名,比方 .js/.cjs/.mjs,或者在 package.json 中装备 "type": "module" 属性,咱们能够在任何文件中无缝切换 importrequire()

在内部,Bun 将一切模块翻译为 CJS 并完成 Node 的 node_modules 解析算法。这是否能如期作业是另一回事:

  • ESM 模块经过预解析,以便在履行代码之前处理进一步的导入问题。动态导入是或许的,但只能被视为最后的手段。
  • CJS 模块在履行代码时按需加载依靠。动态导入的问题较少。

履行顺序在某些 App 中兹事体大,这便是 Node 约束咱们在单个文件中运用 ESM 或 CJS 的原因。

Web API

Bun 内置了对浏览器中可用的 Web 规范 API 的支撑,比方 fetchJSONsetTimeout 等。Deno 将这些 API 引进其服务器运转时,使 Web 编码更加一致。Node 正在迎头赶上,但诸如 fetch 等功用最近才在 Node 18 中推出。

Bun API

Bun 附带了高度优化的规范 API,用于常见操作,比方文件读取、文件写入、HTTP 服务、SQLite 查询和暗码哈希。

WebSocket 与 HTTP 一起支撑,无需 ws 等第三方模块:

Bun.serve({
  port: 8000,
  fetch(request) {
    return new Response('Hello from the Bun server!');
  },
  websocket: {
    open(ws) { ... },
    message(ws, data) { ... },
    close(ws, code, reason) { ... },
  }
});

TS 和 JSX 支撑

与 Deno 相同,Bun 也有一个内置于运转时的 JS 转译器。咱们能够运转 JS、TS、JSX 或 TSX 文件,而无需第三方依靠项。举个栗子:

bun index.ts
bun index.jsx
bun index.tsx

包办理器

咱们能够在任意 Node 项目中直接运用 Bun 作为 npm 代替品。举个栗子:

bun install
bun add <package> [--dev|--production|--peer]
bun remove <package>
bun update <package>

Bun 将模块缓存在 ~/.bun/install/cache/ 中,并运用硬链接将它们拷贝到项目的 node_modules 目录中。因而,系统上的一切项目都引用同一库的单个实例。这能够削减磁盘空间,并将装置功用进步 30 倍。

实时重载

咱们不需求相似 nodemon 的东西,由于 bun 可履行文件具有 -watch 标志,能够在修正文件时重启脚本或测验。

咱们能够运用相似的 —hot 模式,Bun 会监督更改,并软重载模块。一切文件都会重新评估,但大局状况依然存在。

测验

Bun 供给了一个与 Jest 兼容的 bun:test 测验运转器,支撑快照测验、模仿和代码覆盖率。举个栗子:

import { test, expect } from 'bun:test'
test('2 + 2', () => {
  expect(2 + 2).toBe(4)
})

从 Jest 或 Vitest 迁移很简略,由于从 @jest/globalsvitest 导入在内部重新映射到 bun:test,不需求更改代码。

脚本打包

Bun 是一个 JS/TS 打包器和紧缩器,能够针对浏览器、Node 和其他渠道的代码。Bun 受到 esbuild 的启发,并供给了兼容的插件 API:

// 简略构建
Bun.build({
  entrypoints: ['index.js'],
  outdir: 'build'
})

基准测验表明,Bun 的速度是 Go 编译的 esbuild2 倍,而且具有相似的紧缩节省。与 esbuild 不同,Bun 不支撑 CSS 打包,但考虑到有一个通用的插件 API,这或许会完成。

发动和履行速度

运用 bun run <script> 而不是 npm run <script> 一般会比 npm run <script> 发动 App 快 150 毫秒。这或许是一个小改进,但速度比 Node 快 4 倍,而且在运转许多指令和构建脚本时会很明显。运用 TS 时功用提升会更大,由于没有转译步骤。

Windows 试验性版别

Bun 的原生版别很快就会推出适用于 Windows 的版别,目前它是高度试验性的,能且仅能支撑 JS 运转时,没有进行功用优化。包办理器、测验运转器和打包器等功用均被禁用,直到它们安稳停止。

目前,Windows 用户能够在适用于 Linux 的 Windows 子系统上装置 Bun —— 如果您正在履行任何繁重的 JS 作业,这依然是最佳挑选。

高潮总结

Bun 是一个老练的 JS 运转时,但 Node 依然是关键使命项目或留传 App 的冠军。咱们应该尝试运用 bun start 运转 App,但是咱们的代码库越大,它在无需修正的情况下顺畅履行的机会就越小。

关于新项目而言,Deno 或许是比 Bun 更好的挑选,由于它更老练且功用更完好。

Bun 很棒,而且正在活跃开发,但它初出茅庐。运转时是安稳的,但现阶段很少有人会押注它的长时间未来。

Deno 开始朝着自己的方向开展,但不得不后退。关于许多 Node 开发者而言,Deno 过于激进且不兼容。

Bun 从一开始就供给了兼容性和速度 —— 鉴于 Bun 运用不同的 JS 引擎,这是一项相当大的成就。Bun 是否能完成挨近 100% 的 Node 兼容性还有待观察,但咱们能够将其视为留传项目中某些东西集的直接代替品。

Bun 声称的速度令人印象深刻,但很少有人抱怨 Node 的原始功用,尤其是当 Node 随着每个版别的发布而改进时。有些结构很慢,但这一般是由于膨胀而不是运转时的固有过错。

目前,Node 依然是无可争议的 JS 运转时霸主。很少有人会由于挑选 Node 而被辞退,但 Bun 避免了 Deno 的一些失误,并敏捷成为一个有招引力的挑选。

本期论题是 —— 你开始体会 Bun 了吗?

欢迎在本文下方自由言论,文明同享。谢谢咱们的点赞,掰掰~

前端猫猫教》每日 9 点半更新,坚持阅览,自律打卡,每天一次,进步一点

Bun 的 Windows 安稳版行将发布,重温 Bun 运转时