自发布以来,Deno 就引起了 JavaScript 社区的广泛关注。作为 Node 创建者设计的 JavaScript 运行时,你可能会期待这两个项目有很多相似之处,事实也确实如此。然而,它们也存在重要的差异,这意味着你不能简单地用一个替换另一个。
本文将探讨 Deno 与其“老前辈” Node.js 的关系,以帮助理解它们的共同点和不同之处。 (如果你想先了解 Deno 的核心内容,可以查看我们最近的介绍文章。)
这两个项目都是 JavaScript 运行时,允许在计算机上(在 Web 浏览器之外)执行 JavaScript 代码。让我们看看它们在语言支持方面的比较。
当前 Node 的 LTS 版本(截至撰写本文时为 v12.18.1)支持现代 JavaScript 语法和功能。它还支持大约 75% 的 ES2020 规范。 ECMAScript 模块也受支持,但目前仅被归类为实验性:你需要使用 .mjs 文件扩展名,或在项目的 package.json 文件中添加属性 "type": "module"。
为了在 Node 上运行 TypeScript(或任何其他语言),代码需要编译成 V8 引擎可以执行的 JavaScript 代码。有几种不同的方法可以做到这一点,各有优缺点,因此启动和运行意味着必须选择其中一种并遵循必要的设置过程。
我没有找到任何关于 Deno 支持的 JavaScript 规范的提及,但由于它也在后台使用 V8,所以我假设它与 Node 的支持级别相似。我自己的测试表明,Deno 支持 ES2020 功能,如 Promise.allSettled() 和 globalThis 关键字。 ECMAScript 模块是默认的,除非你使用 Node 兼容性库(稍后会详细介绍),否则不支持 CommonJS 模块。
TypeScript 在 Deno 中作为一等语言受支持,这意味着它可以开箱即用:无需先安装额外的工具来转换为 JavaScript。当然,V8 引擎本身并不原生支持 TypeScript,因此 Deno 仍然在后台转换代码,但这对于你作为开发人员来说是完全无缝透明的。
我也找不到 Deno v1.0.1 使用哪个版本的 TypeScript 的信息,但它支持可选链和空值合并(但不支持私有类字段),这可以将其定位为 TS 3.7。
Deno 和 Node 都向开发者公开自己的 API,允许我们编写可以执行有用的操作的程序,例如读取和写入文件,以及发送和接收网络请求。
Node 首次发布时,没有内置对 Promise 的支持。因此,大多数异步操作的 API 都是使用错误优先回调编写的:
<code class="language-javascript">const fs = require('fs'); fs.readFile('readme.txt', (err, data) => { if (err) { // 处理错误 } // 否则处理数据 });</code>
即使 Node 开发人员现在可以使用 Promise 和 async/await 语法,为了保持向后兼容性,API 仍然需要回调。
Deno 的 API 旨在利用现代 JavaScript 功能。所有异步方法都返回 Promise。Deno 还支持顶级 await,这意味着你可以在主脚本中使用 await,而无需将其包装在 async 函数中。
<code class="language-javascript">try { const data = await Deno.readFile('readme.txt'); // 处理数据 } catch (e) { // 处理错误 }</code>
开发团队还决定尽可能使用 Web 标准,这意味着他们在实际可行的情况下实现了浏览器 API。Deno 提供全局 window 对象和 addEventListener 和 fetch 等 API。访问 fetch 特别好,因为在 Node 中,你必须为此使用 polyfill 或第三方库。
Deno 提供了一个兼容性层,旨在允许你重用现有的 Node 包。它尚未完成,但它目前支持通过 require() 加载 CommonJS 模块,以及其他一些功能。
包管理是 Deno 与 Node 的工作方式大相径庭的一个领域。由于 Deno 仍处于早期阶段,其方法是否会证明是有利的还有待观察。
你可能知道,Node 自带一个名为 npm 的包管理器,用于安装和管理第三方包。npm 主要与在线 npm 注册表一起使用,大多数可用的第三方包都列在其中。
当你使用 npm 将包安装到你的项目中时,package.json 文件用于指定包名称和可接受的版本范围。然后,包本身(以及它所依赖的任何包)将下载到项目内的 node_modules 文件夹中。
Deno 完全取消了对包管理器的需求。相反,包是通过 URL 直接链接的:
<code class="language-typescript">import { Response } from "https://deno.land/std@0.53.0/http/server.ts";</code>
在第一次运行你的代码时,Deno 会获取并编译所有依赖项。然后它们将缓存在文件系统中,与你的项目分开,因此后续运行速度会更快。
与 npm 的 package-lock.json 文件类似,Deno 允许你指定一个锁定文件,该文件将用于确保只使用与你最初导入的精确版本匹配的依赖项。
一门语言的繁荣与否取决于其生态系统的活力,因为生产力依赖于不必重新发明轮子!在这里,Node 目前似乎占据优势。
Node 拥有一个庞大而多样的库和包生态系统。在其发布的 11 年里,已在 npm 注册表上注册了超过一百万个包。当然,质量可能差异很大,许多包不再积极维护,但这仍然是 Node 开发人员的一大优势。
正如我们在上一节中看到的,Deno 正积极尝试避免对包管理器或注册表的需要,允许脚本直接从任何公共 URL 导入模块。当然,如果你不知道有什么,就很难导入包,因此 Deno 网站维护着一个兼容第三方模块的列表。截至撰写本文时,列表中有 707 个模块。
Deno 尝试改进开发者体验的一种方法是提供一个标准库,其中包含用于常见任务的辅助程序和实用程序。所有模块都由核心开发人员审核,以确保高质量、可靠的代码。有用于处理命令行参数和为终端输出着色的模块——这两者对于 Node 来说都只有作为第三方包才可用。
也许 Deno 比 Node 最受吹捧的改进之一是权限系统。让我们看看原因。
Node 运行时非常宽松,允许代码完全访问计算机的网络和文件系统。如果未经检查,第三方代码有可能对你的系统造成破坏。
改进安全模型是 Ryan Dahl 在设计 Deno 时特别想要做的事情。默认情况下,所有代码都在安全的沙箱环境中执行。这可以防止代码访问文件系统、网络和环境变量等内容,除非使用命令行参数明确授予访问权限。
<code class="language-javascript">const fs = require('fs'); fs.readFile('readme.txt', (err, data) => { if (err) { // 处理错误 } // 否则处理数据 });</code>
更好的是,在允许读取或写入文件系统或访问网络时,你可以提供白名单。这意味着你可以将 Deno 程序的读/写访问权限限制在项目的 data 文件夹中,例如,限制任何潜在的恶意损坏。
在结束之前,我还想谈一件事。如果你浏览一下手册的工具部分,你会注意到 Deno 为我们提供了一些不错的“额外功能”!以下是内置工具,可以使开发体验更好一些:
本文的目的不是为了宣传 Node 或 Deno,而是为了比较和对比两者。你现在应该了解这两个运行时之间的相似之处,也许更重要的是,它们之间的区别。
Deno 为开发者提供了一些特别的优势,包括强大的权限系统和一流的 TypeScript 支持。设计决策和额外的内置工具旨在提供一个高效的环境和良好的开发者体验。
另一方面,Node 周围拥有一个庞大而完善的生态系统,已经发展了十多年。这加上大量的文档和教程,可能使 Node.js 在未来一段时间内成为一个安全的选择。
快速了解 Deno。我们的 Deno 基础系列文章将帮助你迈出进入 Deno 世界的第一步,并且我们正在不断地添加内容。我们将提供你成为专业人士所需的教程。你可以在更新我们的 Deno 简介后随时参考我们的索引:
➤ Deno 基础
什么是 Node.js?Node.js 是一个基于 Chrome 的 V8 JavaScript 引擎构建的开源跨平台 JavaScript 运行时。它允许开发人员执行服务器端 JavaScript,从而可以构建可扩展且高性能的 Web 应用程序。
什么是 Deno?Deno 是一个基于 V8 引擎构建的用于 JavaScript 和 TypeScript 的安全运行时。它是由最初开发 Node.js 的同一个人(Ryan Dahl)创建的。Deno 旨在解决 Node.js 中存在的一些设计缺陷和安全问题。
Node.js 和 Deno 在架构上有什么区别?Node.js 使用基于回调的异步模型,而 Deno 使用 async/await 等现代功能,使异步代码更易于阅读和维护。与 Node.js 相比,Deno 还具有更模块化和分散的架构。
Node.js 和 Deno 之间的主要安全差异是什么?Deno 采用安全优先的方法,这意味着它默认情况下会限制对文件系统、网络和其他潜在危险操作的访问。相反,Node.js 采用更宽松的模型,开发人员需要手动管理安全设置。
Deno 可以运行 Node.js 模块吗?Deno 旨在与 Web 平台兼容,并且它有自己的模块系统。虽然它可以运行经过一些修改的 Node.js 模块,但通常建议使用 Deno 原生模块以获得更好的兼容性和安全性。
Node.js 和 Deno 如何支持 TypeScript?Node.js 和 Deno 都支持 TypeScript。在 Node.js 中,开发人员通常需要设置一个单独的 TypeScript 编译步骤,而 Deno 原生支持 TypeScript,允许你直接运行 TypeScript 代码而无需额外的配置。
以上是node.js vs deno:您需要知道的的详细内容。更多信息请关注PHP中文网其他相关文章!