阅读 11693

Node之父重构的Deno终于发布了,它终究会取代Node吗?

Node之父是谁?

没错!就是这个叫Ryan Dahl的男人在2009年创造了Node。你看,其实也不是说大神就都没头发,这位大神毛发不是挺旺盛的嘛! 不过既然是在2009年缔造的Node,那么就不得不吐槽那时候的JS了。在2009年的JavaScript啥样大家都知道(大家那时候入行了没),ES5.0(不成熟的ES5)在09年年底才刚刚发布,而ES5.1(咱们现在用的ES5)在2011年6月才开始发布并成为ISO国际标准。

想象一下即使现在有了ES6 ~ ES2020这么新的版本,JS依然经常被大家拿来吐槽,更别提那个ES5都没普及的年代了。 在那时候既没有合适的异步方式也没有模块化,也没有什么包管理啥的。那么这样的JS写大型项目或服务端项目简直就是一场灾难,于是乎就产生了各种模块化方案(Node采用了CommonJS),也有了 npm、node_modules 等各种历史遗留问题。 一方面是当年的 Ryan Dahl 技术没有现在好,思想也没有现在这么全面、另一方面当年的 JS 本来就很坑,用它创造出来的东西肯定不会很完美的。

但是如今的 JS 越来越发展壮大,虽然现在还是很坑,不过比起以前的 JS 来说简直强百倍。不仅有了自己的模块化,还有了 Promise、Proxy、Bigint、块级作用域等一系列非常实用的特性、而且还有更好的 TypeScript 来为 JavaScript 负重前行。而 Node 的历史包袱实在太重,即使想支持一下标准的模块化都不得不把.js变成.mjs以保持兼容。

Deno起因

Node 之父并没有一直在维护 Node,他后来离开了 NodeJS 加入了谷歌,在谷歌他研究的主要方向就是机器学习里面的图像着色和超解像技术。虽然取得了一定的成就,但是 Ryan Dahl 认为现在的机器学习还很简单,离真正的人工智能还有着十万八千里。但是这并不妨碍人们去提升机器学习的技术,因为他相信,总有一天,人工智能会变得越来越完善。

提到机器学习和人工智能就不得不提 python,Node 他爸始终不是很喜欢 Python,久而久之,就想搞一个 JavaScript 的人工智能开发框架(以后前端可能还得再学个人工智能)。等到他再回过头捡起 Node.js,发现这个项目已经背离了他的初衷,有一些无法忽视的问题。

这些啥破玩意?那个又是些什么鬼?原来,他觉得当初自己创建 Node 时失误实在是太多了,他甚至还在 2018 年的 JS 开发者会上列出了自己设计 NodeJS 的十个错误:

  • 没有坚持使用 Promise
  • 没有注重安全性
  • 没有从 GYP 构建系统转到 GN
  • 继续使用 GYP,没有提供 FFI
  • package.json 以及依赖了 npm
  • 在任何地方都可以 require(”somemodule“)
  • package.json 提供了错误的 module 概念
  • 设计了软件界黑洞 node_modules
  • require("module") 可以不写 .js
  • index.js

为了弥补这些错误,他研发了一个新的项目,用来解决他的十个痛点(其实远远不止十个),这个项目就是Deno。

Deno的技术

Node 的底层依赖的是 C++,那 Deno 一样吗?

答案是否定的,一部分程序员可能还记得 Deno 一开始依赖的是 Go 语言,这曾经在 GoLang 社区掀起了不小的波澜。 但是好景不长,后来换成了 Rust。然后好多人借机黑 Go 吹 Rust 了一番。

至于为什么换成Rust,Ryan Dahl说是因为不想同时存在两个GC(Go和TS)

Deno的名字

细心的朋友可能会发现 deno 这四个字母就是 node 的四个字母两两颠倒了一下:

  • de + no = Deno
  • no + de = Node

颠倒 Node 字母的寓意是要颠覆 Node 吗?

其实也差不多,它的意思是:Destroy Node (毁灭Node!

看来 Ryan Dahl 对他的 Deno 很有信心,我是希望它能真的干掉 Node 的,因为它的优点实在是太过于突出啦!

那么接下来我们就来看一看 Deno 的优势都有哪些:

Deno的优势

内置 tsc 引擎,可以直接运行 ts 代码(还是要先编译成JS)。这就不用你每次编写完 ts 代码还要去手动去编译了,而且也不用再去搭建什么 ts-node 之类的了,方便你我他。它的内部会根据文件后缀名判断,如果是.ts后缀名,就先调用 TS 编译器,将其编译成 JavaScript。如果是.js后缀名,就直接传入 V8 引擎运行。

由于是用 Rus t语言开发的,Rust 原生支持 WebAssembly,所以它也能直接运行 WebAssembly。它的异步操作不使用 libuv 这个库,而是使用 Rust 的 Tokio 库来实现 event loop。

那么为什么不像 Node 一样用 C++ 而是选择用 Rust 呢?主要是因为 Rust 提供了很多现成的模块,对于 Deno 来说,可以节约很多开发时间。也许是看到了 Rust 提供了很多现成模块,Deno 也决定在自己的项目中添加许多现成模块。

Deno 具有安全控制,默认情况下脚本不具有读写权限。如果脚本未授权,就读写文件系统或网络,会报错。想要读写文件系统的话必须使用要参数,显式打开权限才可以。Ryan 在总结 Node 的十个错误时曾说:V8 引擎本身有很好的 sandbox 架构,但是有时候 Node 本身却没有好好利用,例如有可以直接读取 Memory 的例子,或者 linte r可以直接使用网络功能等的漏洞。从 npm 下载了一个包就任由他运行了,这其中存在着很大的安全隐患。

Deno 支持 Web API,尽量跟浏览器保持一致。它提供 window 这个全局对象,同时支持 fetch、webCrypto、worker 等 Web 标准,也支持 onload、onunload、addEventListener 等事件操作函数。不像Node,Web API 和 Node 的 API 不一致只会增加开发者的学习成本。以后 window 全局对象就可以不仅仅只局限于浏览器环境啦!

Deno 只支持 ES 模块,跟浏览器的模块加载规则一致。既没有 npm,也没有 npm_modules 这个无底洞,同时不支持 CommonJS 模块,也不需要 package.json 文件。所有模块通过 URL 加载,比如 import vue from ".vue.org"(绝对地址)或 import vue from './vue.runtime.js'(相对地址)。因此,Deno 不需要一个中心化的模块储存系统,可以从任何地方加载模块。但是,Deno 下载模块以后,依然会有一个总的目录,在本地缓存模块,因此可以离线使用。也就是说其实还是有一个类似于 npm_modules 的文件夹。

Deno 内置了开发者需要的各种功能,不再需要外部工具。打包、格式清理、测试、安装、文档生成、linting、脚本编译成可执行文件等,都有专门命令,不知道会不会在干掉 Node 的路上顺便把 Webpack 也给干掉。

Deno的劣势

虽然这么一对比,感觉 NodeJS 完全不是对手,但是有一点是 Deno 暂时望尘莫及的,那就是巨大的生态。

就像 C# 和 Java 一样,他们之间真的差距那么巨大吗?其实并没有吧,但是流行度差这么多有很多原因是因为生态。

就像华为想搞自己的鸿蒙系统,即使真的能比安卓优秀,但是安卓巨大的生态就足够领先很多年。当年 Windows Phone 系统不就是这么输的么?啥软件都没有,自然没人愿意去买 Windows Phone 手机。

Ryan 说了,Deno 现在不打算对 Node 做兼容处理,也就是说很多东西在 Node 能用但是在 Deno 上用不了,能不能真的干掉 Node 就要看广大造轮子爱好者们了,看看他们愿不愿意在 Deno 身上再造一个。

如果 React、Vue 以后都从 Deno 身上建生态了,那么 Deno 的前途就真的光明了,希望那一天能够早点到来。

重要提示

之前曾经发生过一群中国程序员以一种类似于贴吧灌水的形式在 Deno 项目的 issue 下面大量发:

  • 学不动啦
  • 求别更新
  • 前端太难了

之类,其他 issue 都被淹没,导致 Ryan 直接关闭 issue,中国程序员在世界上的形象更加一落千丈。如果学不动了可以不学,不找那种高端岗位就是了,又不是所有岗位都要求你是全栈。

但请不要给全体中国程序员抹黑,谢谢!

往期精彩文章

文章分类
前端
文章标签