Nodejs:Deno 会在短期内取代 Node 吗?

发布于 1周前 作者 htzhanglong 来自 nodejs/Nestjs

Nodejs:Deno 会在短期内取代 Node 吗?

Deno 是什么?

Deno v1.0.0 已于 5 月 13 日正式发布。

其开发者为 Ryan Dahl,他的上一个项目是 Node,相信我们大部分人都了解。

作为 Node 之父,Ryan Dahl 认为 Node 自从他把项目移交出去后,Node 的走向越来越背离了他的初衷,并且存在着很多无法解决的问题,所以他决心重新开发一个新的项目去解决这些问题,这个项目就名为 Deno 。目标则是Destroy-node 。

那么,这样是不是就意味着 Deno 即将替代 Node,成为 Node 的下一代产品?我们应不应该从现在就开始放弃 Node 开始使用 Deno 呢? 让我们一起看看。

起源

在 2018 年,Ryan 在柏林进行了一次演讲,这是他第二次关于 JS 的公开演讲,第一次再 2009,那次是宣布 Node 项目的诞生。

在这次演讲中,除了主要介绍他认为 Node.js 的几大问题和不可避免的许多 Bug 外,在演讲快结束时,他揭开了当时还是个小项目名为 Deno 的面纱,因为和 node 命名有着千丝万缕的联系,那时大家认为这个项目就是 Node.js v2,它将会解决和完善 ry 提到那些问题。

两年后的 5 月 13 日,Deno 1.0 终于正式发布了,它是一个全新的服务端 JavaScript 运行时,使用 Rust 而不是 C++开发,由于 Rust 原生支持 WebAssembly,所以它也能直接运行 WebAssembly 。基于 Tokio 平台(它提供了所有 JavaScript 所需的异步操作),内置 V8 和 tsc 引擎,可直接解释 JavaScript 和 TypeScript 。

安全集成

默认情况下,Node.js 给你的访问权限比较高,这意味着你拥有读写文件系统、对外发出请求、访问环境变量等行为。虽然作为开发人员,拥有这种级别的访问权限对开发过程非常好,但如果你在开发过程中有一点疏漏,将来对你的应用也会产生安全风险。

而在 Deno 这,默认情况下脚本不具有读写权限,必须显式通过命令行参数来启用或禁用对不同安全功能的访问。因此,如果需要脚本能够访问 /etc 文件夹,可以通过下面命令行执行:

deno --allow-read = / etc myscript.ts

这就类似于其他平台处理安全性的方式。如果你是 Android 用户,那么肯定有很多应用程序要求你允许它们访问你手机内的不同资源,例如联系人、电话、文件夹等,同样的概念也可以在这里应用。通过将这些标志用作执行脚本的命令行的一部分,你可以提供代码所需的权限。

更完整的标准库

自从 Node 的第一个版本发布以来,JavaScript 已经改进了它的标准库,但与其他语言相比,它仍有相当长的路要走。Deno 也试图改进这一点,它声称拥有一个非常完整的标准库,允许开发人员使用官方工具执行基本任务,而只需要对复杂任务使用外部库(ala NPM)。

本质上,Deno 开箱即用工具为终端文本添加颜色,处理外部数据结构(如 Binary 、CSV 、YAML 和其他),生成 UUID,甚至编写 WebSocket 。还可以使用其他更基本的模块,例如文件系统访问、日期助手函数、http 相关函数等等。

集成 TypeScript

如果你对 TypeScript 非常熟悉,那么使用 Deno 将会更加容易上手,因为它原生可以直接运行 TS 。

另外,Deno 不需要任何外部工具去支持多语言,它内部会根据文件后缀自动判断其使用的语言解释引擎。

虽然默认情况下 Deno 会处理很多事情,但您可以使用自己的 tsconfig.json 文件覆盖配置:

deno run -c tsconfig.json [your-script.ts]

默认配置使用的是严格模式,因此如果发现任何不合格的代码都会立即得到提示。

放弃 NPM 和 node_modules

Deno 决定完全放弃 NPM 和 node_modules, 因为 npm 逻辑越来越复杂,node.js 对外部模块几乎没有任何安全验证措施,另外 node_modules 也越来越臃肿且难以管理。

那么,Deno 是如何处理依赖关系呢?它是通过 url 加载所有模块的:

import * as log from "https://deno.land/std/log/mod.ts";

所以,Deno 不再需要拥有一个集中的存储库,之前的 package.json 也不再需要了,现在通过在名为 deps.ts 的文件中包含了模块列表及其各自的 URL,简化了依赖管理。但版本管理控制怎么办呢?作者已经想到了,可在 URL 上指定包的版本,deps.ts 的文件示意:

export { assert } from "https://deno.land/[email protected]/testing/asserts.ts"; export { green, bold } from "https://deno.land/[email protected]/fmt/colors.ts";

由于这个文件的存在,在内部运行时,依赖项将被重新导出,这就能让应用程序的不同模块都引用相同的源。

如果您想更新任何模块的版本,可以通过修改 deps.ts 中 URL 的版本信息。另外,虽然没有了 node_modeules 目录,但依赖项仍然会下载并隐藏在你的硬盘中,供你离线使用,如通过需要重新下载,只需在命令中添加—reload 命令即可。

还有什么?

Deno 还包括其他特性,比如自动测试器、调试器、文件监视器等开箱即用的工具。但其中一些只是语言提供的 API,您需要编写自己的工具才能使用它们。

以 Deno.watchFS 向您提供的文件监视器 API 为例,如果你正在寻找类似于 nodemon 的解决方案,那么你可以自己构建它。下面是一个解决类似问题的 23 行脚本:

最后,它会在短期内取代 Node.js 吗?

虽然 Deno 的很多想法和理念非常好,也确实解决了很多问题。但作为一个从 Node 发布之初就开始用的团队,我认为 PHP 、Python 甚至 Ruby(更不用说 Java 或.NET)都不能与在后端拥有 JavaScript 和异步 I/O 模型相提并论。这些年来,Node(和 JavaScript)不断发展,以满足业界的需求。

在我看来,虽然 Deno 是以 Destroy-node 为己任而开发的,但就目前来讲,Deno 取代 Node 仍不可能,Node 的占有率太高了,生态也足够完善,基本属于想要什么功能都能在社区中找到,所以基本无需担心。而 Deno 还在孵化初期,企业很难去放弃已经成熟的技术转而投入更大的精力使用它。但它未来的前景还是令人期待的, 也许在越来越多的行业头部企业分享过它们的使用经验后,Deno 的存在也会越来越为人所知。


42 回复

通过 url 引入模块,目测最终还是要有个中心仓库的,不然敢在重要项目里随便用?


通过 url 引入这个事已经在 Golang 的包管理看到了,那个恶心……

安全集成 这块完全扯淡。按他这个逻辑,其他所有语言 C/C++、Python 、Go 等等都有安全风险。

Node.js 的访问权限不是比较高,而是正常水平,他想高也高不了,能绕过系统拿到 root 权限吗?明明就是用在桌面领域的东西,还要搞手机那套。而且这个还是给开发人员用的,并不是普通用户。

也就 npm 这块说得过去,但要改进 npm 和 node 本身并没有多大关系。

我也没看懂到底如何解决了 node_module 的问题

#4
参考 golang 的方案
相同的 module 只存一份 不是会像现在每个项目一大堆

太简单了,传到自己的私有仓库不就完了

哦感谢明白了,这也就只是解决了文件重复,占用过大的问题。

#5
是的 还有说是因为 node 的标准库太杂 质量参差不齐 会提供一套标准库
deno 一开始是 golang 写的 因为 gc 和 v8 的 gc 有冲突 所以后来改成 rust 了
但是受 golang 思想或者说启发 nedo 不少参考到了 golang 的方案

#8
nedo => deno

配图真是生动,每次安装 node 的项目,module 就得几小时

不会,因为没有痛点。

在包管理的问题上,重新走 go 走过的老路,犯同样的错误

这种包管理 太恶心了…

求同存異就好,何必見異思遷。Deno 當然會越來越好,但目前來看,兩者不在一個維度。Node 要認真學習,Deno 可以提前預習。

ryan 啥时候说过 destroy node 了,以讹传讹。。deno 就是 node 反过来玩了个梗,从来就没想过取代 node,也不可能取代。

不明白为啥造一个东西出来就非得取代另一个,之前也是各种 wasm 彻底取代 js,都是搞技术的还不明白针对场景选择合适工具?

go mod 那里恶心了啦. 通过 url 来定位 module 有什么问题的吗?
就算不符合自己的期望也不至于用上 [恶心] 这种词吧.

仔细研究了一天, 个人看法他好像并没有解决当初自己提出的那些问题 .
1. npm ( yarn 等 可以继续演进可以变得不那么黑洞)
2. 安全问题, 他也没能虚拟出读写空间, 权限就是要么给,要么不给, 那该出问题还是出问题
3. 和 npm 生态, 和 web 生态好像都不太兼容 (可能是因为现在太早吧)

结论: 我不太看好 deno . 不过他要是成功了 , 限制死所有人都用 stric 模式写 typescript 那应该多美好啊

node 到现在还没有取代 php 来着,deno 继续展望个十年

短期不行,得长期吧。比较看好的是 deno 和 rust 、typescript 、wasm 结合起来的 superpower

赞同,如果觉得恶心,应该提出具体的例子以及场景进行阐述……

生态才是最重要的,而 deno…

前端一直想替代后端
但是折腾来折腾去一直是把自己折腾够呛
到现在 ts 还没替代 node
deno 先等等吧

贵圈真是乱

登上 CSDN 首页

用 yarn 挺快,没有迁移的动力,对我而言

怎么可能呢傻猪猪

假如我有一个依赖指向的是 url.com/[email protected],开发的时候是好的。但是,在某个时间里,库的作者在没有更改版本号的情况下引入了 breaking change 。也就是说同样的 url 指向的是不同的文件。接下来要在新服务器上部署,会不会突然发现起不来?

都是我很看好的改进,比 Node 更适合写命令行小程序了

我非常看好 deno,短时间内无法取代,我们可以预期下 5 年后的。node 的生态环境是很容易迁移到 deno 中来的。

这块应该有 checksum 设计。golang 就是,有 go.sum 。发现冲突,需要排查是包被篡改了,还是有人不按照规范来。

#28 使用的时候回缓存到本地,你不放心可以把缓存也放到服务器上一起部署,官方是这样说的

node_modules 真的是恶心,里面几万个小文件…
按理说 node 和 npm 出来的时候已经有不少成熟的包管理工具了,然而并没能借鉴到优点,反而创造出了别人不存在的问题。

没太觉得 node_modules 恶心了,反正我又不对着 node_modules 目录开发。倒是 npm,拒绝使用 node-sass 。
deno 这个全局 API 确定不是送塔?不看好。

deno 短期不会的,生态很重要,慢慢发展看

我觉得,node 应用能较低成本的迁移到 deno 的话,还是可以的?

如果 deno 能够编译运行前端三大框架( Angular,React 和 Vue )的话,相信推广的会很快的,毕竟大多数都是将 node 作为前端工具链的

不乱不是贵圈,不过我喜欢

除非什么时候 C 语言被替代了

你就不能换成 yarn 或是换下源,还想直接出国?

别说短期,长期也不可能取代。

deno 不能复用 node 生态,之前的所有 npm 包,都要重新造一遍。
目前没有发现有什么特别的理由让我从 node 转 deno 。

针对“Deno会在短期内取代Node吗?”这一问题,作为IT技术专业人员,我的观点如下:

在短期内,Deno不太可能完全取代Node.js。Node.js自2009年发布以来,已经建立了成熟而强大的生态系统,这是其持续被广泛使用的重要原因。而Deno,虽然由Node.js的创始人Ryan Dahl牵头开发,且在设计上解决了Node.js的一些痛点,如安全性、模块加载和依赖管理等,但它目前仍处于发展阶段,生态系统相对较小。

以下是一些关键点的对比:

  • 安全性:Deno默认不允许访问文件系统和网络,除非显式授予权限,这增加了安全性。
  • 模块系统:Deno使用ES Modules,而Node.js早期使用CommonJS(但新版已支持ES Modules)。
  • 生态系统:Node.js拥有庞大的社区和丰富的包生态系统。

此外,虽然Deno内置了TypeScript支持,且可以通过URL直接获取依赖,简化了模块管理,但这些优势目前还不足以让Deno在短期内完全取代Node.js。

示例代码如下,展示了在Node.js和Deno中如何启动一个简单的HTTP服务器:

// Node.js
const http = require('http');
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});
server.listen(3000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:3000/');
});
// Deno
import { serve } from "https://deno.land/std@0.184.0/http/server.ts";
const s = serve({ port: 3000 });
console.log("http://localhost:3000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

综上所述,Deno和Node.js各有优势,选择哪个取决于具体需求。

回到顶部