JavaScript 运行时可帮助您构建高级的、服务器驱动的 JavaScript 项目,这些项目不依赖于用户的浏览器来运行。
有几种运行时可供选择,老牌坚定至高无上地位的 Node.js受到 Deno 和 Bun 的挑战。Deno是由最初创建Node.js的开发人员Ryan Dahl在2009年制作的最新项目。Deno旨在通过细粒度访问控制来提高其安全性,并提供更现代的功能,例如本机TypeScript支持和更好的Web兼容性。
与此同时,Bun是最新的新贵,提供极快的速度,并显着优于其竞争对手。但是,它仍处于测试阶段,并且有一些空白需要填补才能完全投入生产(1.0 版目前于 2023 年 9 月 7 日发布)。
JavaScript 运行时允许您在浏览器之外运行应用程序代码。这意味着您可以将站点作为托管应用程序交付。或者,您可以选择将 JavaScript 运行时用于通用脚本。
您选择的运行时将对应用程序的性能产生重大影响,请求处理和数据库访问速度差异很大。它还会影响开发的易用性和可伸缩性。
除了可用的不同功能以及它们如何影响性能之外,开发人员体验也很重要。团队的偏好(例如他们对运行时的体验以及他们进行试验的意愿)都将决定哪种运行时适合您。您喜欢稳定性还是速度?您是否希望本机 TypeScript 支持具有更丰富的运行时或更可自定义的环境?这些只是您在决定运行时时可能会问自己的几个问题示例。了解每个运行时提供的内容可以帮助您做出最明智的决策。
在根据性能、稳定性和安全性比较这些运行时之前,让我们对每个运行时进行基本概述:
Node.js 是 JavaScript 运行时的卫冕冠军,并被 Stack Overflow 开发人员评为 2023 最受欢迎的 Web 技术。它由Ryan Dahl创建并于2009年推出。公平地说,它彻底改变了JavaScript进入市场时你可以做的事情。有了它,开发人员可以使用JavaScript创建高级后端驱动的应用程序。
今天,有一个以 Node.js 为中心的庞大生态系统,拥有丰富的资源和库。但与任何运行时或技术一样,总有改进的余地。这就是 Deno 和 Bun 在 JavaScript 运行时环境中添加选项的地方。
Deno 是一个基于 Rust 的 JavaScript 运行时。与Node.js一样,它是由Ryan Dahl创建和推出的,希望改进Node.js中提供的内容。您可以在JSConf EU的录音演讲中看到和听到更多关于Ryan在Deno背后的动机。
它的主要重点之一是提高Node.js的安全性。在 Deno 中,必须显式启用文件、网络和环境访问,以便不太可能出现通常由这些区域引起的安全问题。它还旨在更好地支持JSX和TypeScript,以及更面向Web标准。为了简化部署,它将应用程序作为单个包含的可执行文件提供。
Deno还围绕它提供了一个工具生态系统,使开发人员能够快速启动他们的项目。Fresh是为Deno构建的Web框架,Lume是他们的静态站点生成器。
Bun 是最新的运行时,争夺您的注意力。由Zig提供支持,其目标是成为一个多合一的运行时和工具包,专注于速度,捆绑,测试和与Node.js包的兼容性。它最大的吸引力之一是它的性能明显比Node.js和Deno都要快。如果它能够实现所有这些,这将成为一个非常有吸引力的提议。
关于它的性能,Bun 维护者提供了一个运行 HTTP 处理程序的示例基准测试,该处理程序使用 React 渲染服务器端页面。这导致 Bun 每秒处理大约 68,000 个请求,而 Deno 和 Node.js 分别处理大约 29,000 个和 14,000 个请求。这是很大的区别。Jarred Sumner定期在Twitter上提供有关Bun开发的最新信息以及最近的基准测试,因此请务必关注他以了解最新情况。
Bun 还包括基于 JavaScript 和 TypeScript 的项目的捆绑和任务运行功能。与Deno类似,它提供了单个二进制文件,并内置了Web API支持。它还支持一些具有 npm 兼容性的 Node.js 库。
现在,让我们更详细地了解一下差异,重点关注性能、支持和社区、稳定性、安全性和附加功能。
让我们直奔主题,包子赢了。我们之前了解了它的性能功能,即它每秒可以处理多少个请求,这非常令人印象深刻。在数据库操作方面,情况类似。使用 Bung 的基准示例加载 SQLite 的罗斯文数据库时,每秒的平均查询如下所示:
在 Node.js、Deno 和 Bun 之间的另一个比较中,Bun 是处理并发连接最快的。它的每秒请求数也相当高。例如,对于 10 个并发连接,Bun 每秒实现 110,000 个请求,而 Node.js 为 Deno 实现 60,000 个和 67,000 个请求。随着并发连接数的增加以及每个运行时的性能,这种趋势仍在继续。
虽然对用于性能测试的场景的有效性存在一些争议,但 Bun 仍然是赢家。Node.js在所有比较中排在最后,在数据库速度方面做得特别差。Deno 和 Node.js 通常相距不远,Bun 远远超过了他们两个。虽然 Node.js 在这方面落后,但 Yagiz Nizipli 正在领导 Node.js 中几个方面的性能改进工作。例如,将 URL 解析速度提高 ~80-90%。
Bun的速度一直是其开发人员的主要关注点,并使用Safari中的JavaScriptCore。而Deno和Node.js使用与Chrome相同的V8 JavaScript引擎。有计划通过删除编译二进制文件中的死代码来进一步改进 Bun(到目前为止,它已经部分实现)。
除了快速运行之外,Bun 还设计为快速启动 - 目的是在旋转多个实例时保持性能。这使其成为动态扩展应用程序的不错选择。如果您遇到突然的流量高峰,需要快速创建实例,Bun 在设计时考虑到了这一点,以使您的服务尽快可用。
每年都有一个名为 JavaScript 状态的开发人员调查。在其中,有一个问题围绕着参与者经常使用的运行时,有近3万受访者。2022 年最新调查的结果也将 Node.js 描绘成明显的领导者,Deno 落后于 5.3k 票,Bun 获得约 1.2k 票。这是可以预料的,看看这些数字在即将到来的 2023 年调查结果中如何变化将是很有趣的。也许我们会看到Deno和Bun的一些新趋势。
作为老牌玩家,Node.js提供经过验证的性能,为全球2.1%的网站提供支持。这是一个已知的数量,也是大量项目所依赖的产品。如果您确实遇到问题,很可能有人知道如何解决它。
Deno 的 1.0 版于 2020 年 5 月发布,被认为是第一个稳定版本。然而,采用速度一直很慢,也许是因为没有“用户感知”的差异化因素来赢得开发人员的集体支持。自 1.0 版本发布以来,它在改善开发人员体验方面取得了长足的进步,同时在每个版本中保持稳定性,以便开发人员可以在几乎没有影响的情况下进行升级。
在撰写本文时,Bun 已于 2023 年 9 月发布的 1.0 版本。因此,自测试版发布以来,它的稳定性和对 Node.js 核心 API 的覆盖率显着提高,并且随着社区中越来越多的人希望在他们的项目中采用它,它可能会继续下去。
在使用 npm 进行依赖关系管理时,安全性可能是一个弱点,并且在 Node.js 之上构建时扩展到一般的应用程序安全陷阱。创建更安全的运行时是 Deno 创建的驱动因素之一,它围绕着对敏感 API 的细粒度访问控制,例如网络请求、文件系统操作和其他核心功能。Node.js在这方面也不甘落后。Node.js 20引入了一个权限模型,允许与Deno类似的安全方面。
有很多资源可以帮助您学习安全实践,例如Node.js安全最佳实践文章和 OWASP 备忘单等。让开发人员了解常见错误可以帮助您构建安全的 Node.js 应用程序。
Deno 通过要求对正在运行的应用程序中的某些操作具有显式权限来消除 Node.js 中固有的一些安全问题。例如,为了使您的应用程序能够访问从文件系统读取,您必须在启动时使用 --allow-read 标志启动它。您可以在其权限文档中查看这些内容的完整列表。您还可以在运行时与此权限系统交互,这使您能够以编程方式请求和撤销权限。使用该 --allow-run 标志时要小心其子进程,因为生成的子进程没有与 Deno 进程相同的安全限制,并且可能会使 Deno 的安全沙箱失效,从而导致权限提升。
Bun 仍然很新,很难获得有关其安全性的信息。它的相对不成熟意味着您应该谨慎使用它,并密切关注安全补丁的更新和公告。一旦它变得更加稳定,就计划引入安全审计。
Node.js最近引入了一些功能,使其更符合Deno和Bun的功能。它现在有一个内置的测试运行器,内置的TypeScript支持正在积极讨论中。
Deno 包括一个依赖检查器和代码格式化程序。它部署到单个可执行文件的能力也是一个加分项。使用 Deno 设置服务器时,其文档中描述的基本方法涉及从其他地方提取代码。代码看起来并不比 Node.js 复杂得多,但由于依赖项是通过 URL 加载的,因此感觉会有点不同。
下面是代码的精简示例:
import { serve } from "https://deno.land/[email protected]/http/server.ts";
const handler = async (_request: Request): Promise<Response> => {
const resp = await fetch("https://api.github.com/users/denoland", {
// The init object here has an headers object containing a
// header that indicates what type of response we accept.
// We're not specifying the method field since by default
// fetch makes a GET request.
headers: {
accept: "application/json",
},
});
return new Response(resp.body, {
status: resp.status,
headers: {
"content-type": "application/json",
},
});
};
serve(handler);
Bun 的其他功能包括转译器和包管理器。正如名称中所暗示的,它还包括捆绑功能,为您提供了原本需要其他工具的功能,例如 Snowpack 或 rollup.js。它还通过其JavaScript简化器具有死代码消除功能。
如果使用 Bun 作为任务运行器,它的速度可能是一个很大的优势。它声称启动需要~5毫秒,而Node.js需要~25毫秒。这似乎没有显着差异,但是当您将其与需要随着时间的推移运行的多个任务相结合时,它可能会影响加快开发工作流程。
在决定使用哪个项目时,应考虑所有早期功能。您的优先级将根据您的用例和项目需求而有所不同。
Bun 显然是速度的赢家,但由于它仍然很新,使用它存在风险。它会发展出其他两个的稳定性吗?也许。无论哪种方式,如果您是一个颠覆者,希望通过在速度上超越竞争对手来掀起波澜,Bun 提供了这个机会(在大多数情况下)。
Node.js的最大优势是它的成熟度和生态系统的规模。你会发现很多开发人员都理解它。然而,Deno和Bun具有更新的吸引力,这总是让开发人员兴奋不已。
与Node.js相比,Deno也有很多优势,其功能集使开发更加顺畅,并且可以轻松构建高质量的复杂项目。它是安全的,但虽然比Node.js快,但与Bun相比,它有点慢。
一般来说,Node.js仍然是最安全的选择,并且有成功的记录。Deno 有很多值得推荐的地方,其现代功能使其成为希望构建新事物的开发人员的不错选择。如果您最关心速度或只是想驾驭新技术的最前沿,Bun 是首选工具。