什么是Deno,它与Node.js有什么不一样?

做者:Maciej Cieslar

翻译:疯狂的技术宅javascript

原文:https://blog.logrocket.com/wh...前端

未经容许严禁转载java

Node.js 的建立者 Ryan Dahl 花了一年半的时间研究 Deno,这是一个新的 JavaScript 运行时环境,能够解决Node 的全部问题。node

不要误解个人意思,Node 自己就是一个很棒的服务器端 JavaScript 运行时环境,主要是由于它拥有庞大的生态和 JavaScript。然而,Dahl 认可他应该考虑更多的东西:安全性、模块和依赖性等。webpack

并非说 Dahl 认为这个平台在短期内会增加多少。不过早在 2009 年,JavaScript 仍然是这种奇怪的小众语言,每一个人都在取笑它,并且还确实许多功能。git

什么是Deno,它的主要特色是什么?

Deno 是一个基于 V8 构建的安全的 Typescript 运行时,V8 是 Google 的 JavaScript 运行时引擎。程序员

它由如下技术构建:github

  • Rust(Deno的核心是用Rust编写的,Node用C ++编写)
  • Tokio(用Rust编写的事件循环)
  • TypeScript(Deno 支持 JavaScript 和开箱即用的 TypeScript)
  • V8(google 在 Chrome 和 Node 等中使用的 JavaScript 运行时)

那么让咱们来看看 Deno 提供的功能。web

安全性(权限)

Deno 最重要的功能之一就是注重安全性。面试

与 Node 相反,Deno 默认在沙箱中执行代码,这意味着运行时无权访问:

  • 文件系统
  • 网络
  • 执行其余脚本
  • 环境变量

咱们来看看权限系统的工做原理。

(async () => {
    const encoder = new TextEncoder();
    const data = encoder.encode('Hello world\n');

    await Deno.writeFile('hello.txt', data);
    await Deno.writeFile('hello2.txt', data);
})();

该脚本建立了两个名为 hello.txthello2.txt 的文本文件,其中包含一个 “Hello world” 消息。该代码正在沙箱中执行,所以它没法访问文件系统。

还要注意,咱们用的是 Deno 命名空间而不是 fs 模块,就像在 Node 中同样。 Deno 命名空间提供了许多基本的辅助函数。若是使用命名空间,就会失去浏览器兼容性,稍后将对此进行讨论。

这样运行它:

deno run write-hello.ts

将会提示如下内容:

Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]

实际上咱们会被提示两次,由于来自沙箱的每次调用都必须请求许可。固然,若是咱们选择 allow always 选项就只会被问一次。

若是选择 deny 选项,将抛出 PermissionDenied 错误,并且因为咱们的代码中没有任何错误处理逻辑,所以将终止该进程。

若是用如下命令执行脚本:

deno run --allow-write write-hello.ts

会发现没有提示,两个文件都已被建立。

除了文件系统的 --allow-write 标志外,还有 --allow-net--allow-env--allow-run标志用来启用网络请求、访问环境、以及运行子进程。

模块

Deno 就像浏览器同样,经过URL加载模块。不少人起初在看到服务器端带有 URL 的 import 语句时感到困惑,但它确实有意义 —— 只要你能忍受:

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

您可能会问,经过 URL 导入包有什么大不了的?答案很简单:经过 URL,Deno 软件包能够在没有集中注册的状况下进行分发,例如 npm,还有不少问题的解释能够在这里找到。

经过URL导入代码,咱们使包的建立者可以在他们认为合适的地方托管本身的代码。 不须要 morepackage.json 和 node_modules。

当启动应用程序时,Deno 会下载全部导入的模块并对其进行缓存。一旦它们被缓存,Deno 将不会再次进行下载,直到经过 --reload 标志特别要求。

这里有几个重要的问题:

若是网站出现故障怎么办?

因为它不是集中式的注册,托管该模块的网站可能会因多种缘由而被删除。这取决于它在开发期间的状态——或者更糟糕的是,在生产过程当中是有风险的。

正如前面提到过的,Deno 缓存了下载的模块。因为缓存存储在本地磁盘上,Deno 的建立者建议在版本控制系统(即git)中检查它并将其保存在存储库中。这样,即便网站出现故障,全部开发人员均可以访问下载的版本。

Deno 将缓存存储在 $DENO_DIR 环境变量下指定的目录中。若是不本身设置变量,它将被设置为系统的默认缓存目录。能够在本地存储库中的某处设置 $DENO_DIR 并将其签入版本控制系统。

我是否必须一直经过URL导入?

不断输入网址将很是繁琐。值得庆幸的是,Deno 为咱们提供了两种选择避免这样作。

第一个选项是从本地文件从新导被出导入的模块,以下所示:

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

假设上面的文件名为 local-test-utils.ts。如今,若是想再次使用 testassertEquals 函数,能够像这样引用它:

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

所以,是否从 URL 加载它并不重要。

第二个选项是建立一个导入映射,能够先在 JSON文 件中指定:

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

而后导入它:

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

为了使它工做,必须经过包含 --importmap 标志告诉 Deno 导入映射:

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

那么包版本控制呢?

包提供程序必须支持版本控制,但从客户端来看,只需在 URL 中设置版本号便可,以下所示:https://unpkg.com/liltest@0.0.5/dist/liltest.js

浏览器兼容性

Deno 旨在与浏览器兼容。从技术上讲在使用ES模块时,能够没必要借助任何构建工具(如 webpack)来使咱们的程序能够在浏览器中使用。

可是,像 Babel 这样的工具会将代码转换为 ES5 版本的 JavaScript,所以,即便在不支持该语言全部最新功能的旧版浏览器中,代码也能够运行。但这也是以在最终文件中包含大量没必要要的代码并使输出文件膨胀为代价的。

由本身决定咱们的主要目标是什么,并相应地作出选择。

TypeScript支持开箱即用

Deno 能够无需任何配置文件就可以轻松使用 TypeScript。同时能够用纯 JavaScript 编写程序并执行它们而不会有任何麻烦。

总结

Deno 是 TypeScript 和 JavaScript 新的运行时,是一个有趣的项目,如今已经稳定发展了很长一段时间。可是在被认为可以稳定用于生产环境以前还有很长的路要走。

借助它的分布式方法,它须要从集中式软件包注册表(即npm)中释放 JavaScript 生态系统。

Dahl 说他但愿在夏天结束前发布 1.0 版本,因此若是你对 Deno 的将来发展感兴趣,能够访问它的 GitHub


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎继续阅读本专栏其它高赞文章:


相关文章
相关标签/搜索