Deno vs. Node.js哪个更好

449 阅读8分钟

Deno vs. Node.js哪个更好?

Node.仍然是使用最广泛的JavaScript运行时环境,但Deno更安全,并带来了现代的优势。比较Deno和Node.js,决定哪一个适合你的下一个项目。

在这篇文章中,你将了解到Node.js和Deno,CommonJS和ECMAScript模块的区别,在Deno中使用TypeScript,以及用Deno Deploy进行更快的部署。最后我们会有一些说明,帮助你在下一个开发项目中决定使用Node.js还是Deno。

什么是Node.js?

Node.js是一个跨平台的JavaScript运行环境,对服务器和桌面应用程序都很有用。它运行一个在系统中注册的单线程事件循环来处理连接,每个新的连接都会引起一个JavaScript回调函数的启动。回调函数可以用非阻塞的I/O调用来处理请求。如果有必要,它可以从一个池中生成线程,以执行阻塞或CPU密集型操作,并在CPU核心之间平衡负载。

与大多数使用线程扩展的竞争性架构(包括Apache HTTP Server、各种Java应用服务器、IIS和ASP.NET以及Ruby on Rails)相比,Node使用回调函数进行扩展的方法需要更少的内存来处理更多的连接。

Node应用程序并不局限于纯JavaScript。你可以使用任何可转换为JavaScript的语言;例如,TypeScript和CoffeeScript。Node.js集成了谷歌Chrome V8 JavaScript引擎,它支持ECMAScript 2015(ES6)语法,而不需要像Babel这样的ES6-ES5转码器。

Node的大部分效用来自于它的大型包库,可以通过npm 命令访问。NPM,即Node包管理器,是标准Node.js安装的一部分,尽管它有自己的网站

基于JavaScript的Node.js平台是由Ryan Dahl在2009年推出的。它是作为Linux和MacOS的Apache HTTP服务器的一个更可扩展的替代品而开发的。NPM,由Isaac Schlueter编写,于2010年推出。Node.js的本地Windows版本在2011年首次亮相。

什么是Deno?

Deno是一个用于JavaScript和TypeScript的安全运行时,它已被扩展为WebAssemblyJavaScript XML(JJSX)及其TypeScript扩展,TSX。Deno由Node.js的创造者开发,它试图重新想象Node,以利用自2009年以来JavaScript的进步,包括TypeScript编译器。

与Node.js一样,Deno本质上是一个围绕谷歌V8 JavaScript引擎的外壳。与Node不同的是,它的可执行图像中包括TypeScript编译器。创建这两个运行时的Dahl说,Node.js有三个主要问题:基于集中式分布的模块系统设计不佳;必须支持大量的传统API;以及缺乏安全性。Deno修复了所有这三个问题。

Node的模块系统问题在2022年中期的一次更新中得到了解决。

CommonJS和ECMAScript模块

当Node创建时,JavaScript模块的事实标准是CommonJS,这也是npm 最初支持的。从那时起,ECMAScript委员会正式批准了ECMAScript模块,也被称为ES模块,jspm 包管理器支持。Deno也支持ES模块。

在Node.js 12.12中加入了对ES模块的实验性支持,并从Node.js 16开始稳定。TypeScript 4.7也支持Node.js 16的ES模块。

在JavaScript中加载一个CommonJS模块的方法是使用require 语句。加载ECMAScript模块的方式是使用import 语句,同时使用匹配的export 语句。

最新的Node.js有CommonJS和ES模块的加载器。它们有什么不同?CommonJS加载器是完全同步的;负责处理require() 调用;支持文件夹作为模块;如果在require() 调用中遗漏了扩展名(.js, .json, 或.node),则会尝试添加。CommonJS加载器不能用于加载ECMAScript模块。ES模块加载器是异步的;负责处理import语句和import() 表达式;不支持文件夹作为模块(目录索引如./startup/index.js ,必须完全指定);不搜索扩展名;对于JavaScript文本文件只接受.js、.mjs和.cjs扩展名。ES模块用于加载JavaScript CommonJS模块。

为什么Deno更有利于安全

众所周知,Deno比Node提高了安全性。主要是因为Deno在默认情况下,不会让程序访问磁盘、网络、子进程或环境变量。当你需要允许其中任何一项时,你可以用一个命令行标志来选择,它可以是你喜欢的细粒度;例如,--allow-read=/tmp--allow-net=google.com 。 Deno的另一个安全改进是,它总是在未捕获的错误中死亡。相比之下,Node将允许在未捕获的错误后继续执行,结果不可预知。

你可以同时使用Node.js和Deno吗?

当你考虑在你的下一个服务器端JavaScript项目中使用Node.js还是Deno时,你可能会想是否可以将它们结合起来。这个问题的答案是肯定的 "也许"。

首先,很多时候,使用Deno的Node包就可以了。更妙的是,许多常见的绊脚石都有解决方法。这包括使用Deno标准库的std/node 模块来 "填充 "Node的内置模块;使用CDN来访问绝大多数的npm 包,并在Deno下工作;以及使用导入地图。此外,Deno从Deno 1.15开始有一个Node兼容模式。

缺点是,Node的插件系统与Deno不兼容;Deno的Node兼容模式不支持TypeScript;而且一些内置的Node模块(如vm)与Deno不兼容。

如果你是一个Node用户,考虑切换到Deno,这里有一个小抄来帮助你。

在Deno中使用TypeScript

Deno将TypeScript视为第一类语言,就像JavaScript或WebAssembly一样。它将TypeScript(以及TSX和JSX)转换为JavaScript,使用内置在Deno中的TypeScript编译器和一个名为swc 的Rust库的组合。当代码经过类型检查(如果检查被启用)和转换后,它被存储在一个缓存中。换句话说,与Node.js或浏览器不同,你不需要用tsc 编译器为Deno手动转译你的TypeScript。

从Deno 1.23开始,Deno中默认没有TypeScript的类型检查。由于大多数开发人员通过他们的编辑器与类型检查器进行交互,所以当Deno启动时再次进行类型检查并没有很大的意义。也就是说,你可以用Deno的--check 标志来启用类型检查。

用于快速部署的Deno Deploy

Deno Deploy是一个分布式系统,允许你在全球范围内靠近用户的边缘运行JavaScript、TypeScript和WebAssembly。与V8运行时深度集成,Deno Deploy服务器提供最小的延迟并消除不必要的抽象。你可以使用Deno CLI在本地开发你的脚本,然后在不到一秒钟的时间内将其部署到Deno Deploy的管理基础设施,而不需要配置任何东西。

建立在与Deno CLI相同的现代系统上,Deno Deploy以全球可扩展的方式提供最新和最伟大的网络技术:

  • 在网络上构建。使用fetch、WebSocket或一个URL,就像在浏览器中一样。
  • 对TypeScript和JJSX的内置支持:类型安全的代码,以及直观的服务器端渲染,无需构建步骤。
  • 网络兼容的ECMAScript模块。就像在浏览器中一样导入依赖关系,不需要明确的安装。
  • GitHub集成。推送到一个分支,审查已部署的预览,并合并发布到生产。
  • 极其快速。在一秒内完成部署;在全球范围内为用户提供服务。
  • 从一个URL进行部署。只需一个URL就可以部署代码。

Deno Deploy有两个层级。免费层限于每天100,000个请求,每月100GiB的数据传输,以及每个请求10ms的CPU时间。专业层的费用为每月10美元,包括每月500万个请求和100GiB数据传输,另外每月每百万个额外的请求为2美元,超过所含配额的数据传输为0.30美元/GiB;专业层允许每个请求有50ms的CPU时间。

生产中的Deno

根据Deno的说法,它在Slack、Netlify、GitHub和Supabase都在积极生产。如果有案例研究解释这些公司如何使用Deno,我还没有找到。

选择哪一个Node.js还是Deno?

正如你所期望的那样,哪种技术更适合你的用例,答案取决于许多因素。我的底线是。如果你有一个现有的Node.js部署,而且没有损坏,那么不要修复它。如果你有一个新的项目,你打算用TypeScript编写,那么我会强烈考虑Deno。然而,如果你的TypeScript项目需要使用多个没有Deno对应的Node.js包,你就需要权衡Deno项目的可行性。从概念验证开始基本是强制性的。如果不尝试,很难预测你是否能让某个Node.js包在Deno中工作。