几天前的 JavaScript Weekly 里推送了一条名为 “A Look at Deno: A New JavaScript Runtime” 的视频,视频的内容是 Deno 的作者(同时也是 Node.js 项目的最初发起人与维护者) Ryan Dahl今年 4 月初的 JS Fest 大会上做的关于 Deno 的演讲。

Deno, a new way to JavaScript

看完视频感觉这个项目挺有趣,于是花了一点时间做了一些了解,记录如下。

为何要开发 Deno?

关于为何要开发 Deno,Ryan 其实已经在去年的 JSConf EU 上已经讲过了。在这个主题为 “10 Things I Regret About Node.js” 的分享中,Ryan 回顾了在他看来当初开发 Node.js 时留下的 10 大遗憾。由于 Node.js 现在已经广泛应用于各个领域,为了保证兼容性,对 Node.js 底层进行大规模改造已经不现实。于是 Ryan 宣布他决定开发一个全新的 JavaScript Runtime 以解决当初的种种缺陷。这便是 Deno。

10 Things I Regret About Node.js

PS: 这个演讲也是干货满满,非常推荐大家观看。
PPS: 敢于在公众面前大方的讨论自己设计软件的种种缺陷,这种精神本身就很值得敬佩。

Deno 有何特点?

在我看来,Deno 的几个突出特点有以下几个:

下面逐一介绍。

内置 TypeScript 支持

顾名思义,Deno 的运行时内置了 TypeScript 引擎,我们可以直接通过 Deno 命令运行 .ts 文件,省去了编译流程以及本地开发环境的配置。

安全性提升

Deno 会在一个安全沙箱里执行我们的的程序代码,如果程序需要访问文件系统、网络或是派生子进程则必须得到开发者的明确授权,否则会产生一个 PermissionDenied 的异常。

我们通过一个例子来说明。

以下是一个使用 Deno 开发的模拟 *nix 环境下 cat 命令的小程序。它将读取参数中的文件并将内容打印到终端中。

(async () => {
  for (let i = 1; i < Deno.args.length; i++) {
    let filename = Deno.args[i];
    let file = await Deno.open(filename);
    await Deno.copy(Deno.stdout, file);
    file.close();
  }
})();

我们运行该脚本,提示 Deno 申请读取该文件并询问我们是否授权。当我们选择不授权时,Deno 抛出权限异常并退出。

下面我们手动选择授权:

文件读取成功。

如果觉得每次通过交互式的操作授权麻烦,Deno 还提供了命令行参数来指定开放哪些权限:

基于 ES 标准的模块系统

随着 ES2015 标准的发布,JavaScript 有了正式的模块标准。Deno 的模块系统即建立在 ES 的模块标准之上,它仅支持 import 语句,不支持 require 方法。

为了尽可能和浏览器保持兼容,它还支持 import 一个 URL:

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

因此,如果你的代码没有使用 Deno 命名空间下的方法,那么它应该可以无缝的运行在浏览器环境中。

既是运行时又是包管理器

Deno 首次遇到远程 import 时会首先将该文件下载到本地,后续再执行该脚本时,就不会再从网络上下载,而是直接从本地缓存中读取已经缓存的副本,从而支持离线运行代码。本地缓存可以通过环境变量 $DENO_DIR 指定具体路径。

基于这一点,Deno 并没有配套的类似于 npm 的包管理,同时也没有和 package.json 对应的描述文件。

简化的安装方式

Deno 只提供一个可执行文件供下载,只要你下载该文件到本地,你就有了运行 Deno 脚本所以依赖的全部环境。这一点使得维持本地多个版本的 Deno 运行时变得非常简单。

小结

以上就是 Deno 的一些基本信息,如果想了解更多内容,可以查看完整的 Deno 用户手册

另外需要注意的一点是,目前 Deno 还在快速迭代中,现有版本可能包含了各种各样的 bug,同时 API 也随时可能更改。因此现阶段还不推荐在任何非学习场景中使用 Deno。

延伸阅读