2024 年你应该使用 Node、Bun 还是 Deno?

大家好,这里是大家的林语冰。

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

免责声明

本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 Should you use Bun or Node.js or Deno in 2024?

本期共享的是 ------ 如何为我们的下一个大型项目选择正确的 JS 运行时!2024 构建 JS 筑基的现代 API 相对简单。我们可以使用 Express 等库,并在几分钟内启动可用的 API。但是,现在最具挑战性的部分是选择正确的 JS 引擎。

尽管备胎生态非常庞大,但我们必须了解三大 JS 运行时:

  1. Node
  2. Deno
  3. Bun

那么,我们应该为下一个大型 JS 项目选择什么运行时呢?事情没有那么简单。重要的是要了解每个运行时都有优缺点。因此,本文通过比较 Bun、Node 和 Deno 的优势和缺陷等来测评它们!

Node

Node 是用于服务器端开发最广泛使用的 JS 运行时。

Node 运行在谷歌 Chrome 的 JS V8 引擎之上,确保快如闪电且高度可靠的性能。Node 最有益的方面之一是事件循环(event loop)。

事件循环允许我们在单个线程上运行整个 App,而不会遭遇任何阻塞。它能够智能地将异步阻塞操作转移到第三方库 libuv 上,libuv 执行所有异步 I/O 操作,并让 Node 主线程在调用堆栈空闲时处理回调。此外,通过集成 worker 线程(工作者线程),开发者现在能够启动独立的 JS 运行时,并模拟多线程和并行处理。

Node 开发 API 的优势

  • 高度可扩展性和性能:Node 通过非阻塞 I/O 和可扩展性提供更高的性能,并由事件驱动架构支持,这使得 Node 非常适合用户群不断增长的实时数据密集型 App。
  • 拥有众多库和框架的成熟生态系统:Node 拥有一个元气满满的生态系统,拥有丰富的库和框架,为开发者提供了一个全面的工具包,可以跨 Web 开发和实时 App 进行高效编码。
  • 大型且活跃的社区支持:Node 拥有一个生机勃勃且元气满满的社区,可以转化为定期更新和改进、以及广泛发布的模块,开发者可以轻松地将这些模块合并到它们的项目中。

Node 开发 API 的缺陷

  • 单线程性质导致的性能瓶颈:由于 Node 是单线程的,因此它不适合繁重的计算,或需要 CPU 密集型的任务。虽然但是,引入 worker 线程后,Node 能够执行 CPU 密集型操作,而不会遭遇性能瓶颈。
  • 异步编程中的回调地狱 :所谓"回调地狱",指的是 Node 中的异步函数彼此嵌套得深不见底,以至于代码变得复杂且混乱,就像试图捋顺一碗意大利面条一样。幸运的是,可以通过使用 Promisesasync/await 等解决方案来避免这种情况,这有助于使代码更清晰、更易于阅读。

Deno

Deno 是一种新兴的 JS/TS 运行时,致力于解决 Node 的某些缺陷。

Deno 默认优先考虑安全性

在没有适当权限许可的情况下,这可以确保我们的代码无法访问文件或网络。Deno 运行在 JS V8 引擎之上,并采用 Rust 设计,这意味着它的速度快如闪电!

此外,Deno 还通过合并内置实用程序(比如用于网络的 fetch)来采用当前的 Web 标准,与浏览器处理 JS 的方式保持一致,并提供更具凝聚力的编码体验。

Deno 开发 API 的优势

  • 内置安全性:Deno 在安全的沙箱环境中运行,需要明确的权限才能访问文件系统、网络和环境,从而降低漏洞风险。
  • 改进的开发体验:Deno 通过依赖检查器和代码格式化等内置工具增强了开发者的工作流程,并提供原生 TS 支持,使开发者能够关注编码而不是配置。
  • 使用 URL 简化模块管理:Deno 通过利用 URL 直接从 Web 获取依赖,而无需包管理器,简化模块管理,从而简化代码库中的模块解析。

Deno 开发 API 的缺陷

  • 不如 Node 生态系统成熟:Deno 作为 Node 的新潮备胎方案,正在开发其生态系统,预计通过社区贡献实现增长。与 Node 强大的生态系统相比,开发者目前看到的现成解决方案可能较少。
  • 第三方库的可用性有限:虽然 Deno 正在不断发展,但其第三方库的选择并不像 Node 的宝库那么广泛。开发者可能会发现自己处于前沿,有时需要利用可用资源发挥创意,甚至需要自己制作资源。随着 Deno 生态系统的发展,库的数量将会增加,从而拓宽每个人的工具范围。

Bun

Bun 是 2023 推出的一个新兴的运行时和工具包。

Bun 是一个快速、一体化的工具包,用于运行、构建、测试和调试 JS/TS,从单个文件到全栈 App

而且,有了 Bun,我们所要做的就是开箱即用。举个栗子,我们不再需要安装 nodemon/dot-env 等工具,因为 Bun 能够在开发者模式下开箱即用地热重载,同时默认也能选用 .env 文件。

此外,Bun 还提供内置的 websocket 服务器,并使用自己的包管理器 bunx,速度比 npm 快 5 倍。但是,这还不是全部。Bun 不仅仅是一个 JS 运行时。这是一个一体化的工具包。这意味着 Bun 还提供了开箱即用的功能:

  1. 打包功能
  2. 包管理器
  3. 测试运行器

因此,我们不需要花时间配置项目,也不需要维护复杂的样板项目。相反,我们可以启动一个 Bun 项目并立即开始!

Bun 开发 API 的优势

  • 简单的学习曲线:Bun 是一个一体化工具包!这意味着,我们不必花时间学习模块打包、配置测试框架。Bun 默认执行这些操作。这样我们就可以原地起飞!
  • 更高的性能:Bun 使用 JavaScriptCore 引擎,而 Node、Deno 等运行时使用 JS V8 引擎。JavaScriptCore 引擎已针对更快的启动时间进行了优化,并且通常比其他两个运行时的性能更高。

Bun/ Bun Router 开发 API 的缺陷

  • 社区支持较少:Bun 才诞生不久。因此,Bun 仍然没有一个成熟的问题社区。如果我们严重依赖社区支持,那可能需要在继续之前检查是否有正确的支持。

Node vs Deno vs Bun

1. 性能跑分

让我们来测评一下 Bun、Deno 和 Node。

我们使用 JS 编写一些需要大量内存的数学代码来处理大数据集,考虑复杂计算和海量计算。

一个典型的例子是矩阵运算。这是一个矩阵乘法函数的示例,它在处理大型矩阵时大显身手。

js 复制代码
function generateRandomMatrix(rows, cols) {
  const matrix = []
  for (let i = 0; i < rows; i++) {
    matrix[i] = []
    for (let j = 0; j < cols; j++) {
      matrix[i][j] = Math.random()
    }
  }
  return matrix
}

function matrixMultiplication(a, b) {
  const rowsA = a.length
  const colsA = a[0].length
  const rowsB = b.length
  const colsB = b[0].length
  if (colsA !== rowsB) {
    throw new Error('Incompatible matrices for multiplication')
  }

  const result = new Array(rowsA)
  for (let i = 0; i < rowsA; i++) {
    result[i] = new Array(colsB).fill(0)
  }

  for (let i = 0; i < rowsA; i++) {
    for (let j = 0; j < colsB; j++) {
      for (let k = 0; k < colsA; k++) {
        result[i][j] += a[i][k] * b[k][j]
      }
    }
  }
  return result
}

const matrixSize = 1000 // Adjust the size of the matrix to increase memory usage
const matrixA = generateRandomMatrix(matrixSize, matrixSize)
const matrixB = generateRandomMatrix(matrixSize, matrixSize)

console.time('Matrix Multiplication')
const resultMatrix = matrixMultiplication(matrixA, matrixB)
console.timeEnd('Matrix Multiplication')

我们有 generateRandomMatrix 来创建任意大小的随机矩阵。然后是 matrixMultiplication 将这些矩阵相乘。我们可以使用 matrixSize 变量来决定这些矩阵的大小。

随着矩阵大小的增加,我们会注意到内存使用量也会随之增加。让我们看看 Bun、Node 和 Deno 如何使用此代码执行操作。

我们使用一个名为 hyperfine 的基准测试工具,准备好开始基准测试,让我们运行命令瞄一下会发生什么!

bash 复制代码
hyperfine "bun index.js" "node index.js" "deno run index.js" --warmup=100 -i

上述 shell 命令会在不同的运行时执行上述代码,并且需要几分钟的时间才能提供基准测试结果。

Bun 在管理内存和 CPU 密集型任务方面的熟练程度不仅仅是巧合,它专为速度和最佳性能而设计。如果您的项目需要快速和高效,Bun 被证明是一个绝佳选择。

Bun 不仅与 Node 和 Deno 势均力敌,甚至还有过之而无不及。Bun 经常赶超它们。因此,如果您想构建一个能够在不牺牲功能的情况下提供速度和效率的 App,那么考虑 Bun 是一个值得的选择。

2. 社区比较

另一方面,社区支持对于已经存在了一段时间的运行时是有利的。举个栗子:

  • Node:作为一个经验丰富的"骨灰级玩家",Node 拥有一个繁华的社区。这反映了 Node 在 API 开发中的由来已久且人见人爱。
  • Deno:Deno 正在迅速开拓自己的市场。Deno 得到了一个元气满满、高瞻远瞩、渴望突破界限和创新的社区支持。
  • Bun:Bun 社区相比前两者而言相对较小。这主要是因为 Bun 比它们更新。但是,根据 Bun 的发展方式,毋庸置疑,它很快就会拥有一个庞大的开发者社区!

但是,Node 脱颖而出,它在 API 开发方面的丰富经验培育了一个元气满满且生机勃勃的社区。这个技术爱好者社区始终准备提供协助、交换资源和协作。

尽管 Bun 和 Deno 正在取得长足进步,但 Node 社区仍然难以超越。因此,如果您优先考虑强大的支持网络,Node 是一个可靠的选择。

3. 安全性

Node、Deno 和 Bun 都有独特的安全方法。下面简单介绍一下它们的区别:

  • Node :Node 默认对我们的系统开放,具体取决于可能引入风险的第三方包。npm audit 等工具有助于捕获漏洞。举个栗子:
bash 复制代码
npm audit

另外,使用像 helmet 这样的以安全为中心的中间件可以增强 Node App 的防御:

js 复制代码
const helmet = require('helmet')

const app = require('express')()

app.use(helmet())
  • Deno:Deno 就像一个保险库,脚本被紧紧锁定,除非我们明确授予权限。运行具有有限访问权限的 Deno 服务器,如下所示:
bash 复制代码
deno run --allow-net=example.com server.ts
  • Bun:这个新玩意的目标在于速度,并提供内置的安全功能。虽然但是,Bun 初出茅庐,因此它可能没有像其他方案一样经过那么多安全场景的测试。

显然,Deno 采取了高度宽松的方法,它对 App 拥有的权限持谨慎态度。Deno 以安全性为首要任务构建,在安全沙箱环境中运行,除非明确授权,否则限制文件和网络访问。

虽然 Node 和 Bun 结合了各自的安全措施,但 Deno 的附加内置安全层,使其成为在 API 开发中优先考虑安全性的首选。

因此,如果安全性是您的首要任务,请选择 Deno!

全都要,或是三选一?

前端开发没有银弹。这取决于您的优先事项。因此,收藏本文作为比较这些 JS 运行时的基准。

  • Node:如果您关注"稳定至上",经过多年尝试和测试的稳定可靠的生态系统,那么 Node 是首选运行时。
  • Deno:如果您关注"安全第一",以及最新的编程环境功能,建议使用 Deno。它还支持开箱即用的 TS。
  • Bun:如果您关注"性能至上",尤其是在使用 JS/TS 时,Bun 应该是您的首选。

写在最后

2024 选择正确的 JS 运行时可能看起来令人头大,但了解 Bun、Node 和 Deno 的优缺点可以简化决策。

最终,您的项目的要求、对社区支持的依赖、以及对文档的准备程度,可能在确定最合适的选择中发挥关键作用。

本期话题是 ------ 你目前最常用哪个 JS 运行时,以及你预言未来哪个运行时会脱颖而出?

欢迎在本文下方自由言论,文明共享。谢谢大家的点赞,掰掰~

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

相关推荐
蒜蓉大猩猩1 小时前
Vue3.js - 一文看懂Vuex
前端·javascript·vue.js·前端框架·html5
放逐者-保持本心,方可放逐1 小时前
node.js 入门级基础应用
开发语言·node.js
today喝咖啡了吗1 小时前
node.js知识点总结
node.js
前端Hardy1 小时前
探索 HTML 和 CSS 实现的 3D旋转相册
前端·css·3d·html·css3
小白讲前端1 小时前
酷炫的鼠标移入效果(附源码!!)
前端·javascript·css·html·css3
前端Hardy1 小时前
探索 HTML 和 CSS 实现的模拟时钟
前端·javascript·css·html·css3
山川尔尔_2 小时前
JS手写-this绑定实现
开发语言·javascript·ecmascript
那就可爱多一点点3 小时前
H5页面多个视频如何只同时播放一个?
前端·音视频
谁呛我名字5 小时前
大数据应用开发——数据可视化
javascript·vue.js·echarts
前端郭德纲5 小时前
浅谈React的虚拟DOM
前端·javascript·react.js