几天前的 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 支持
- 安全性提升
- 基于 ES 标准的模块系统
- 既是运行时又是包管理器
- 简化的安装方式
下面逐一介绍。
内置 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。