5 分钟带你了解未来可能推翻 Node 的新轮子 Deno 1.0

2020-06-05 11:07:00 +08:00
 WuJia
关注微信公众号前端技术专栏,回复“资源”免费领取全套视频教程

前言

最近 Nodejs 作者 Ryan Dahl 发布了 Deno 1.0 正式版,圈子一下沸腾起来了。或许你早在两年前就听说了这个东西,但是也有人不知道这个东西是什么,干什么用的,所以今天我将为大家来简单的聊一下这个将来可能会推翻 Node 的新轮子。

正文

什么是 Deno ?

Deno 是一个基于 v8 、rust 和 Tokio 的 Javascript/Typescript 的安全运行时。它在内部嵌入了一个 typescript 的编译器。可以将 typescript 编译成 js 然后运行在 v8 上,并通过 c++ libdeno 实现 js 与 rust 的通信交互,当然 deno 也可以直接运行 Javascript 代码。

已经有了 Node,为什么作者还要写一个 Deno ?

在过去的几年里,JS 标准引入了大量新的语法特性。影响最大的就是 Promis 和模块化。

对于 Node 来说,这两个东西支持的都不是很理想。由于历史原因,Node.js 必须支持回调函数,导致异步接口会有 Promise 和回调函数两种写法;同时,Node.js 自己的模块 CommonJS 与 ES 模块化不兼容,这样就导致无法完全支持 ES 模块化。

另一个原因就是 Node.js 的模块管理工具 Npm,逻辑越来越复杂;模块安装目录 npm_modules 非常庞杂,难以管理。Node.js 也几乎没有安全措施,用户只要下载了外部模块,就只好听任别人的代码在本地运行,进行各种读写操作。 然后 Node.js 的功能也不完整,导致外部工具层出不穷,让开发者疲劳不堪:webpack,babel,typescript 、eslint 、prettier.....

So,由于上面这些原因,作者 Ryan Dahl 决定放弃 Node.js ,重新写一个替代品,来彻底解决这些问题。

如何安装 Deno ?

linux/mac

curl -fsSL https://deno.land/x/install/install.sh | sh

windows

iwr https://deno.land/x/install/install.ps1 | iex

详细可以参考官网查看:https://deno.land/

安全性

Deno 默认安全。相比之下,Node.js 默认拥有访问文件系统和网络的权限。 要在没有授权的情况下运行一个需要启动子进程的程序,比如:

deno run file-needing-to-run-a-subprocess.ts

运行后你会看到一条警示消息

error: Uncaught PermissionDenied: access to run a subprocess, run again with the --allow-run flag

相较于 Node,Deno 默认使用沙箱环境执行代码,这意味着运行环境没有操作以下模块权限:

必须使用参数,显式打开权限才可以,参数分别如下:

例如,要授予 Deno 对 /etc 目录的只读权限,可以这样:

deno --allow-read=/etc

模块机制

Deno 使用浏览器一样的方式,通过 URL 来加载模块。很多人第一次见到在服务端的 import 语句中见到 URL 会感到有点困惑,但对我来说这还蛮好理解的:

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

通过使用 URL 来加载模块,Deno 就可以避免引入一个类似 npm 的中心化系统来发布 package,npm 最近受到了很多吐槽。 通过 URL 来引入代码,可以让包的作者们使用自己最喜爱的方式来维护和发布自己的代码。再也不会有 package.json 和 node_modules 了。 当我们启动应用之后,Deno 会下载所有被引用的文件,并将它们缓存到本地。一旦引用被缓存下来,Deno 就不会再去下载它们了,除非我们使用-- relaod 标志位去触发重新下载。

只能使用 URL 来引用模块吗?

其实,你可以在本地文件中将已经引用的模块重新 export 出来,比如:

export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";

假如上面这个文件叫 utils.ts 。现在,如果我们想再次使用 test 或者 assertEquals 方法,只需要像下面这样引用它们:

import { test, assertEquals } from './utils.ts';

另一种方式就是建一个引用映射表,比如像下面这样一个 JSON 文件:

{
  "imports": {
     "http/": "https://deno.land/std/http/"
  }
}

然后 import 到代码里:

import { serve } from "http/server.ts";

最后为了让它生效,还需要通过--importmap 让 Deno 来引入 import 映射表:

deno run --importmap=import_map.json hello_server.ts

Deno 的命令

Deno 内置了开发者需要的各种功能,不再需要外部工具。打包、格式清理、测试、安装、文档生成、linting 、脚本编译成可执行文件等,都有专门命令。

Deno 的内部结构

下面是 Deno 的部分目录结构图

上图中圈出来的三个文件夹分别是

分别对应 Deno 的 api 层、中间层、和实现层;其中 js 中主要是 typescript 的代码,包含 typescript 的编译器和 Deno 暴露给用户的 api 。libdeno 中主要是 c++代码,用来加载 v8 实例,实现 typescript 和 rust 的通信。src 文件中主要是 rust 的代码,是 Deno 功能的具体实现。例如用户使用 File 实例的 write 方法来写文件,实际上是 api 层( typescript )通过中间层( libdeno )将数据传输给实现层( rust ),最终写文件操作由 rust 去完成。Deno 结合了 Typescript/Javascript 的易用性和 rust 的系统语言能力。

此图可以清晰的表示 js 和 rust 之间的逻辑关系。

总结

就目前来看,Deno 还是一个比较新的东西,功能不稳定,周围生态还不够完整。

So,还不能完全取代 Node.js ,建议先不要用于生产环境,但是现在已经是一个能够使用的工具了,有时间的话可以造造轮子,研究一下也不是不可的。

1444 次点击
所在节点    前端开发
2 条回复
putaozhenhaochi
2020-06-05 11:18:40 +08:00
move to /promote
WuJia
2020-06-05 11:31:42 +08:00
@putaozhenhaochi 挺不错的,可以玩一玩。就是目前生态还不完整

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/678883

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX