JavaScript运行时有什么新选择?Bun 1.0和Node.js与Deno相比有什么优势?

Bun是Node.js和Deno的竞争对手,是一个新的JavaScript运行时。在本文中,将介绍Bun 1.0,以及它可能让你尝试去使用的理由。

历史:Bun在Node和Deno中的定位

Ryan Dahl 于 2009 年发布了 Node.js。虽然它不是第一个服务器端 JavaScript 运行时,但 Node.js 迅速崭露头角。2023 年发布了第 20 版,Node.js 拥有最大的开发生态系统,拥有 320 万个模块,每周下载量接近 5000 亿次。

2020 年,Ryan Dahl 发布了 Deno,它是“noDe”的一种混合体,旨在现代化 JavaScript 开发并解决 Node.js 安全性、API 兼容性、工具和模块管理方面的传统问题。虽然 Deno 受到了积极的评价,但尚未挑战 Node 的主导地位。

2022 年,Jarred Sumner 发布了 Bun,因为他在开发 Next.js 项目时对 Node.js 的速度感到不满。

Bun 使用 JavaScriptCore 引擎,该引擎驱动 WebKit 浏览器,如 Safari,而不是 Node.js、Deno 和 Chrome 中使用的 V8 引擎。

Bun 运行时侧重于性能和开发人员体验。其目标是消除速度慢和复杂性,而不是放弃 JavaScript 的所有优点。

Bun可以比Node.js更快地发展,后者必须与现有的JavaScript和npm生态系统保持(基本)向后兼容。

与Deno一样,Bun对JavaScript和TypeScript本地支持,无需第三方转译器或配置。

Bun正在成为Node.js、Deno、无服务器运行时、构建和测试工具的即插即用替代品。它可以替代npm、npx、yarn、TypeScript编译器、dotenv、nodemon、pm2、Webpack、Babel和Jest,为在单一平台上开发应用程序提供了一个完整的多合一工具箱。

最初的运行时是稳定的,但多亏了近300名开发人员的贡献,Bun版本1.0发布于2023年9月发布。这将不可避免地诱使更多的开发人员迁移到Bun,他们可以享受下文描述的好处。

Bun这个名字有什么含义

来历?“Bun”这个名字的起源不清楚,标志也没有帮助!它可能与食物、蓬松的兔子、“bundle”或者可能是一个简短、容易记住的名字有关,而且bun.sh域名也可用。

JavaScript运行时有什么新选择?Bun 1.0和Node.js与Deno相比有什么优势?

美味的Bun好处

Node.js 和 Deno 使用 Chrome 的 V8 JavaScript 引擎。Bun 选择了 JavaScriptCore 引擎,该引擎驱动 WebKit 浏览器,如 Safari。Bun 本身是用 Zig 编写的,这是一种具有手动内存管理和本机线程处理能力的低级编程语言。其结果是一个轻量级运行时,具有更小的内存占用、更快的启动时间,以及在某些(基准测试)条件下性能可以比 Node.js 和 Deno 快四倍。

与Deno一样,Bun对JavaScript和TypeScript都有本机支持,无需第三方转译器或配置。它还支持.jsx和.tsx文件,以将类似HTML的标记转换为本机JavaScript。还提供了运行WebAssembly编译的.wasm文件的实验性支持。

在内部Bun使用ES模块,支持顶级await,翻译CommonJS,并实现了Node的node_modules解析算法。Bun将模块缓存到~/.bun/install/cache/中,并使用硬链接将它们“复制”到项目的node_modules目录中。因此,您系统上的所有项目都将引用同一库的单个实例,这减少了磁盘空间需求并提高了安装性能。(请注意,macOS安装保留本地版本以提高速度。)

Bun支持Node的package.json,与npm等效命令,以及bunx,这是一个类似npx的选项,可以在单个命令中自动安装和运行包。

bun initnpm init相同,用于创建空项目,但您还可以使用bun create <template> <destination>模板化新项目,其中<template>是一个官方包、GitHub存储库或本地包。

Bun包含一个bundler,用于将所有依赖项导入单个文件,并且可以针对Bun、Node.js和客户端JavaScript。这减少了使用esbuildRollup等工具的需求:

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

无需nodemon等工具,因为bun具有--watch标志,可在修改依赖文件时重新启动脚本或测试。重新启动速度如此之快,以至于可以在每次按键时进行实时重新加载。(是否实用而不会分散注意力是另一回事!)

类似的—hot模式也可用,Bun会监视更改并重新加载模块。所有文件都将重新评估,但全局状态保持不变。

项目.env文件中包含的环境变量会自动加载和解析,使它们在Bun应用程序中可用,因此无需使用dotenv等包。

除了自己的Bun APIs,用于网络、文件访问、子进程等方面,Bun还支持:

Web API

,例如fetchURLblobWebSocketJSONsetTimeout和事件。

Node.js兼容性API,例如consoleassertdnshttppathstreamutil,以及全局变量,包括__dirname__filename*。Bun声称已经完全实现了最常用API的90%,尽管您应该仔细检查与项目特定的API。

最后,Bun具有本机的SQLite3客户端——bun:sqlite,这可以减少某些项目中所需的依赖项数量。

使用 Bun

如果您从项目的开始使用 Bun,它是可靠的。速度比 Node.js 更快,尽管除非您的应用程序执行特定的密集任务,如大量的 SQLite 处理或 WebSocket 消息传递,否则不太可能看到显著的性能提升。

对于较小、较简单的项目,Node.js 的兼容性很好,我成功地使用 bun start 启动了一些脚本,而没有进行任何更改。但对于更复杂的应用程序,可能会失败,并生成在 node_modules 层次结构深处生成的晦涩错误消息。

Bun 与 Node.js 的兼容性

对于较小、较简单的项目,与Node.js的兼容性通常很好。您可能可以启动一些脚本,而不需要进行任何更改,只需使用bun start代替npm start

Bun支持:

内置Node.js模块和API,如fspathhttpconsoleassert

全局变量和对象,如__dirnameprocess

Node.js模块解析算法,以在node_modules中查找文件

Bun 1.0 声称可以运行“几乎任何野外的Node.js应用程序”。我尚未完全相信;复杂的应用程序可能会由于在第三方模块中生成的晦涩错误消息而失败。

ES模块和CommonJS兼容性

Bun支持ESM和CommonJS两种模块系统,还支持顶级await。ESM在Node.js中花了几年时间才推出,生态系统仍然以CommonJS为主导。使用Bun,无需特定的文件扩展名(.js.cjs.mjs)或在package.json中的"type": "module"。您可以在任何文件中交替使用importrequire()

在内部,Bun将所有模块都转换为CommonJS,并实现了Node的node_modules解析算法。是否如预期地工作是另一回事:

ES6模块会在执行代码之前预先解析,以解析更多导入。动态导入是可能的,但应该只被视为最后的选择。

CommonJS模块在执行代码时按需加载依赖项。动态导入问题较少。

在某些应用程序中,执行顺序可能至关重要,这也是Node.js限制您在单个文件中使用EMS或CommonJS的原因。

Web API

Bun具有内置对浏览器中可用的Web标准API的支持,例如fetchRequestResponseURLblobWebSocketJSONsetTimeoutReadableStream。Deno将这些API引入其服务器运行时,使Web编码更加一致。Node.js正在赶上,但像fetch这样的功能最近才在18版中加入。

Bun API

Bun附带了高度优化的用于常见操作的标准API,例如文件读取、文件写入、HTTP服务、SQLite查询和密码哈希。

WebSockets支持HTTP,无需第三方模块,例如ws

TypeScript 和 JSX 支持

与Deno一样,Bun在运行时内置了JavaScript转译器。您可以在不需要第三方依赖项的情况下运行JavaScript、TypeScript、JSX或TSX文件。例如:

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

包管理

Bun将模块缓存到~/.bun/install/cache/,并使用硬链接将它们复制到项目的node_modules目录中。因此,您系统上的所有项目都引用相同库的单个实例。这可以减少磁盘空间使用,并将安装性能提高多达30倍。

实时重载

无需像nodemon这样的工具,因为bun可执行文件具有-watch标志,可以在修改文件时重新启动脚本或测试。

还提供了类似的--hot模式,其中Bun会监视更改并进行软重载模块。所有文件都将重新评估,但全局状态保持不变。

脚本捆绑

Bun是一个JavaScript和TypeScript捆绑器和代码缩小工具,可以针对浏览器、Node.js和其他平台的代码进行目标定位。它受到esbuild的启发,并提供了一个兼容的插件API:

总结:您应该尝试使用 Bun 吗?

Bun 是一个成熟的 JavaScript 运行时,但对于关键任务或传统应用程序,Node.js 仍然是首选。您可以尝试使用 bun start 运行您的应用程序,但是代码库越大,执行而无需修改的机会就越小。

对于新项目来说,Deno 可能比 Bun 更好,因为它更加成熟且功能更完整。

Bun 很棒,而且正在积极开发,但它是新的。运行时是稳定的,但在这个阶段,很少有人会押注它的长期未来。尽管如此,Bun 提出了一些有趣的想法,希望 Node.js 和 Deno 团队都会考虑采纳(CLI API 和自动加载的 .env 请注意!)

延展阅读:

Nodejs 的事件循环机制是如何处理 timers、poll 和 check 队列的?

如何搭建PostgreSQL高可用方案repmgr?详解安装部署与关键组件疑问

Go 1.22的range变更:如何影响代码行为与开发者体验?

中小团队怎么基于PG快速迭代创新?PostgreSQL is all you need!

Nodejs 的事件循环机制是如何处理 timers、poll 和 check 队列的?

咨询方案 获取更多方案详情                        
(0)
研发专家-大橙研发专家-大橙
上一篇 2024年9月1日 上午9:17
下一篇 4天前

相关推荐