背景介绍
毫无疑问,Node.js 就是目前全球最流行、使用范围最广的 JavaScript 运行时环境。但 2018 年亮相的 Deno 同样引发巨大轰动,凭借现代功能和高安全性在开发者群体中疯狂吸粉。
Deno 跟 Node.js 其实系出同门,都是由 Ryan Dahl 倾力打造。人们将 Deno 看作是 Node.js 的继任者,而且修复了后者中一些重要的设计缺陷。虽然现代范十足、年轻气盛,但 Deno 能不能彻底取代 Node.js 仍是个未知数。而且至少就目前来看,这事还八字没一撇,大部分开发者对 Node.js 的表现仍然表示满意。
在本文中,我也跟大家探讨一下 Deno 的普及速度为什么越来越慢,还有人们为什么仍然喜欢 Node.js。最后,咱们再对这两位做一番直接比较。
Node.js 是什么?
Node.js 是一款人气极高的服务器端、开源、跨平台 JavaScript 运行时环境,以谷歌的 V8 JS 引擎为基础。自 2009 年发布以来,它一直在 Web 开发世界占据着主导地位。
Node 主要关注事件驱动的 HTTP 服务器。在处理请求时,它会运行一个向系统注册的单线程事件循环,每个传入请求都会触发一个 JavaScript 回调函数。这些回调函数能够使用非阻塞 I/O 调用处理请求。
此外,Node 还能从池中生成线程,借此解决可能造成阻塞或 CPU 密集型任务。跟大多数通过线程扩展的竞争性框架方案不同,Node 基于回调函数的扩展机制能够以最小的内存占用量容纳更多请求。
凭借着异步 I/O 加事件驱动架构,Node.js 凭借轻量化优势在可扩展、数据密集型和实时 Web 应用程序中占据了显著优势,使其能够运行在各类分发设备之上。
Deno 是什么?
如前所述,Deno 属于新一代的 JavaScript 框架,旨在解决 Node 中的设计缺陷并提供更现代化的开发环境。根据两套框架的缔造者 Dahl 本人的说法,Node.js 具有三个显著缺点:
模块系统设计不当,过于依赖集中分发。
遗留 API 不够稳定。
安全性设计不足。
据称,Deno 一举解决了这三大难题,并带来更好的使用体验。
Deno 是一款 JavaScript、TypeScript 与 WebAssembly 运行时,具备安全默认设置。即除非明确启用,否则其无法访问文件、网络或环境。Deno 建立在 V8 JS 引擎、Rust 和 Tokio 基础之上,采用 Web 平台标准,始终通过单一可执行文件进行分发,并提供内置的开发工具以实现高效、安全的运行时。Deno 包含一组经过审查的标准模块,可确保在 Deno 运行时上正常运行。Deno 还支持原生 TypeScript 文件执行,无需额外做进一步配置。
Deno 对 Node: 主要区别
现在,我们对 Node 和 Deno 做一番直接比较。
第三方软件包管理
借助 Deno,开发人员可以直接通过 URL 安装软件包,而无需借助 npm 之类的集中注册表。尽管直接从 URL 处下载软件包有一定风险——如果托管软件包的服务器遭到入侵,攻击者可能会修改代码以注入恶意功能——但 Deno 提供一种对已下载模块进行缓存的办法,能够有效缓解这方面风险。软件包能够以库的形式被直接导入脚本之内,通过允许直接从任意公共 URL 处获取并运行脚本,Deno 直接跳过了负责模块导入的软件包管理器。当然,从第三方处导入模块仍可能带来安全隐患。在这样的设计下,Package.json 文件和 node_modules 文件自然也没有存在的必要。
相比之下,Node.js 需要使用 npm 来处理所有软件包,而且有着庞大的库和软件包生态系统。
Deno 的模块导入机制比 Node 更灵活,允许开发者从任意来源处导入代码,包括 GitHub 和所托管的任意 CDN 或注册表。这样,我们无需经过下载或安装过程,即可无缝实现模块导入。
API
Node.js 诞生之时,JavaScript 中还没有出现 Promises 或者 async/await 的概念,所以大多数 API 在设计上都接受错误优先的回调函数。这种方法经常会产生冗长而复杂的代码。如今,Node 开发人员已经可以使用 async/await 语法,但同时也需要考虑向下兼容性,否则 API 经常会因变更而影响运行稳定性。
Deno 的情况则完全不同。因为 Deno 已经用上了 await 并支持各种最新 JavaScript 功能,所以这里根本就不需要封装 async 函数。通过这种方式,Deno 帮助开发人员简化了处理流程,能够将各种面向未来的 API 绑定至 JavaScript promises 当中。Deno 还高度关注与浏览器端运行的 JavaScript 代码所使用的 Web 平台 API 相兼容,能够以符合标准要求的方式支持多种流行高级 Web API,包括 Fetch、Web Storage、Web Workers 和 Broadcast Channel,等等。
安全性
提升安全性,也是 Ryan Dahl 决意打造 Deno 的核心原因之一。
Deno 提供安全的沙箱环境,能够禁止对文件系统的访问,所有代码执行也都在这里进行。在访问文件系统之前,Deno 始终会首先提出授权请求。
要获取许可必须借助命令行参数,以防止运行时在未经开发者同意的情况下删除任何文件。Deno 中的各命令行标志都能在运行时上使用,借此启用特定脚本的特定功能。默认情况下,这些功能均处于非活动状态;使用者必须为脚本可能需要的所有元素显式设置相应标志。
这些标志包括:
— allow-env
允许环境访问环境变量获取、环境变量获取等功能。
— allow-hrtime
允许执行高分辨率时间测量。
— allow-net
允许网络访问。
— allow-read
允许文件系统读取访问。
— allow-run
允许运行子进程。
— allow-write
允许文件系统写入访问。
相比之下,Node.js 向来不以高安全性著称(编者注:Node.js 20 新的权限模型:提供了 Node.js 中敏感 API 的权限管控能力。插入微信文章:
https://mp.weixin.qq.com/s/R4Bji3zE7yzbjTycrV1BDQ)。例如,Node 对文件系统的读取和写入访问权限无需单独授予,也不属于沙箱环境。因此,任何第三方库都可能因处置不当而引起风险。另外,Node 用户还需要借助一系列标准安全措施以防止跨站点请求伪造(CSRF)和跨站点脚本(XSS)等威胁,利用这些机制进行日志检查、错误与异常管理,以及用户输入验证。
因此,即使大家已经习惯了安全模块的严格约束,Deno 仍是建立安全环境的最佳选择。
TypeScript 支持
TypeScript 是 JavaScript 的一个超集,允许用户以可选方式添加静态类型。Deno 使用带有缓存技术的 TypeScript 编译器,实现了对 TypeScript 的开箱即用支持。也就是说,Deno 能够直接对 TypeScript 代码进行编译、类型检查和执行,无需将其转换为 JavaScript。
虽然 Node.js 不像 Deno 那样能够天然支持 TypeScript,TS 在 Node.js 社区中也早已成为广受接纳的语言,所以有现成的 TS 包可供使用。大家可以毫不费力地在 Node 上运行 TypeScript。只要安装了 Node 和 npm,您就可以通过 npm install -g typescript 命令在设备上全局安装 TypeScript。接下来,运行 tsc --init 来创建 TypeScript 配置文件,之后使用 TypeScript 编译器 tsc 即可编译您的.ts 文件。
如果您高度依赖于 TypeScript 而且愿意尝试新型框架,那 Deno 无疑是正确的选项。此外,在 Deno 中使用 TypeScript 进行开发时,无需进行任何额外的配置。
开发者为什么喜爱 Node 胜过 Deno?
聊了这么多,可以看到 Deno 明显为开发人员提供了不少特殊功能,例如强大的支持系统和原生 TypeScript 兼容能力。其设计策略和丰富的内置工具,都能给开发人员提供高效的运行时环境和积极的使用体验。
即使如此,Deno 为什么还是没能全面取代 Node?可以看到,Deno 对 Node.js 的替代速度非常慢。尽管有着更现代的框架、也解决了不少设计问题,但开发人员还是更偏爱 Node.js——而且人家的理由也相当充分。
在 Node.js 最初发布时,开发者们就已经开始将其纳入实际应用。多年以来,为了满足软件开发社区的需求,Node 发生了一系列重大变化,如今成为业界使用范围最广的 JavaScript 运行时。由于普及度极高,它也建立起了活跃且庞大的开发者社区。Node.js 的软件包系统以 npm 为基础,功能丰富且易于管理。因此,如果大家的主要诉求集中在灵活性和上手简单度方面,那 Node.js 就是当之无愧的最佳选项。
当然,Node 还远称不上完美。在 Node 仍显落后的各个方面,Deno 都取得了无法否认的重要进步,其中又以安全性和标准合规性为甚。Deno 的单一二进制模式带来了远超 Node 的可移植性,开放模块架构也有望成为未来依赖项导入的客观规范。
哪些因素阻碍了开发者投向 Deno 怀抱?
尽管 Deno 社区也算活跃,但规模实在不大。专为 Deno 量身打造的软件包很有限,Node 兼容层有时候也不够可靠。如果想要使用特定某个库,或者需要技术帮助,那选择 Deno 有可能令您陷入困境。
Deno 的另一个明显短板,就是缺少第三方软件包。而且由于成熟度不高,它无法像 Node.js 那样在现实应用中得到广泛支持。另外,Node.js 有着极高的模块化程度。在 npm 的帮助下,用户可以从单一来源找到大量的库选项。换句话说,每位开发者都可以轻松下载大量软件包来更新自己的应用程序。
此外,借助第三方库,大家完全可以在 Node.js 中实现 Deno 提供的多种功能。所以说,如果我们只是喜爱 Deno 的某些特性,那基本也能在 Node.js 中达成同样的效果,只是过程中需要多一点额外操作而已。
Node 还有另外一张王牌,那就是简单好用的权限管理机制。我们可以在平台上快速收取反馈,无需经过各种授权。Node.js 能以最少的麻烦快速进行编码,很少需要请求特定权限。因此,它特别适合那些需要定期更新、体量庞大而且涉及丰富专业知识的动态项目。
考虑到以上种种因素,可以看到大多数开发人员对于 Node.js 的现状基本感到满意,在短时间内应该也不打算“叛逃”到其他框架中去。
与庞大而繁荣的 Node.js 社区相比,如今的 Deno 只能算是“蹒跚学步”的程度。它还没能在实际生产系统中经受全面测试,开发人员也还在适应这种新的运行时环境。当然,必须承认 Deno 有着巨大的发展前景,也确实在安全性、模块、回调和集中分发系统等层面超越了 Node 的水平。目前,Deno 吸引早期使用者所依靠的主要是大家对于新鲜事物的好奇心。相信随着时间推移,Deno 背后社区的发展壮大将让这个项目逐步成为 Web 开发领域的重量级选项。
总结
在比较了 Deno 和 Node.js 的异同之后,希望大家现在能够理解 Deno 中蕴藏的巨大潜力,以及开发人员为什么对这样一套优秀的框架显得不那么热心。Deno 无疑将继续吸引越来越多的关注,我个人也相信它终有一天会成为能与 Node.js 正面叫板的强大框架。
但软件开发者始终是以完成任务为第一诉求,对于工具的选择必然要基于用例的真实需要。
感谢你愿意耐心看完!
原文链接:
https://cult.honeypot.io/reads/deno-vs-node-main-differences/
评论