什么是Deno?该项目与Node.js有何不同?

Node.js的创建者Ryan Dahl在过去的一年半中致力于Deno项目。 这是新的JavaScript运行时,应该可以解决Node.js固有的问题。

不要误会我的意思。 Node.js平台是运行JavaScript的绝佳服务器端环境。 它的受欢迎程度主要归功于庞大的生态系统,并且实际上是对JavaScript的支持。 但是,Ryan Dahl承认,有关Node.js的一些事情应该引起他的注意。 这尤其涉及安全性,模块以及依赖性管理。


为了辩护,可以说他不知道Node.js平台在相当短的时间内会变得多么流行。 此外,在2009年,JavaScript仍然看起来像是一种有限且陌生的语言,被所有不懒惰的人嘲笑。 还应注意,在那些日子里,如今不常见的许多JavaScript功能都不存在。

什么是Deno?该平台的主要功能是什么?


Deno是在Google开发的V8 JS引擎之上构建的TypeScript安全运行时。 Deno平台是使用以下工具创建的:

  • Rust(Deno核心是用Rust编写的,而Node核心是用C ++编写的)。
  • Tokio(用Rust编写的事件循环)。
  • TypeScript(Deno,没有其他设置,同时支持JavaScript和TypeScript)。
  • V8(Chrome浏览器,Node.js和其他项目中使用的Google JS引擎)。

让我们谈谈Deno平台为我们提供的机会。

安全性(权限)


在特别注意的Deno最重要的功能中,可以注意到安全性。

与Node不同,Deno默认情况下在沙箱中执行代码。 这意味着运行时无法访问以下实体和功能:

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

看一看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名称空间,而不是像在Node中那样引用诸如fs模块之类的东西。 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 { assertEquals } from "https://deno.land/std/testing/asserts.ts"; 

在这里,您可能有一个问题,关于通过URL导入软件包有何特别之处? 这个问题的答案很简单:通过使用URL,无需使用npm之类的中央注册表就可以分发Deno软件包。 Npm最近有很多问题

通过URL组织代码导入允许包创建者在他们认为合适的地方托管他们的代码。 这是权力下放的全部内容。 不再需要package.jsonnode_modules

当我们启动应用程序时,Deno将加载所有导入的模块并对其进行缓存。 缓存它们后,除非我们使用--reload标志明确要求重新加载它们,否则Deno将不会重新加载它们。

关于使用模块的系统,可以提出几个重要的问题。

如果无法访问模块代码所在的资源?


模块代码未存储在集中式注册表中。 出于许多原因,托管此代码的Web资源可能不可用。 在开发过程中,甚至更糟的是,在将项目投入生产时,希望模块主机始终可用是有风险的。

如前所述,Deno缓存加载的模块。 由于缓存存储在本地磁盘上,因此Deno的创建者建议使用版本控制系统(即git)对其进行处理,并将其包括在项目存储库中。 使用这种方法,即使当无法访问存储代码的资源时,所有项目开发人员也将保留对模块下载版本的访问权限。

Deno将缓存存储在$DENO_DIR环境变量指定的文件夹中。 如果我们不配置此变量,则Deno会将缓存存储在标准系统目录中以进行缓存。 可以设置$DENO_DIR ,使其指向我们本地存储库中的某个文件夹。 可以使用您的版本控制系统来处理此文件夹。

I我需要不断通过URL导入模块吗?


定期输入长网址会很快使您感到厌烦。 幸运的是,Deno为我们提供了两种简化此任务的方法。

第一种方法是使用从本地文件重新导出导入的模块的功能。 例如,它可能看起来像这样:

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

假设上述命令所在的文件称为local-test-utils.ts 。 现在,如果我们assertEqual需要testassertEqual函数,则可以这样导入它们:

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

结果,事实证明模块是否通过URL加载都没有关系。

第二个选项是以JSON文件的形式创建一个导入映射:

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

使用类似文件时,导入命令可能如下所示:

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

为了使该方案起作用,您需要在运行脚本时使用--importmap标志来告知系统项目中--importmap映射的用法:

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

module如何管理模块版本控制?


软件包版本控制是他们的责任。 从客户的角度来看,选择正确的软件包版本就像将其添加到URL:
https://unpkg.com/liltest@0.0.5/dist/liltest.js

浏览器兼容性


Deno平台致力于其代码与浏览器的兼容性。 从技术的角度来看,当我们使用ES模块时,我们没有义务使用某些组装工具,例如webpack,它们提供了在浏览器中运行应用程序的能力。

但是,像Babel这样的工具会将现代JS代码转换为ES5兼容代码。 结果,即使在不支持现代JavaScript功能的非更新浏览器中,也可以执行此代码。 但是这种方法也有一个缺点,那就是Web项目捆绑的增长是由于它们获得了大量辅助代码这一事实。

实际上-我们就项目目标做出决策。 我们选择适当的工具。

TypeScript支持


Deno简化了TypeScript的使用,从而使开发人员无需配置任何内容即可运行TS代码。 但是Deno程序也可以用JavaScript编写而没有问题。

总结


Deno是TypeScript和JavaScript的新运行时环境,是一个有趣的项目,它已经展示了一段时间的可持续性。 但是,在可以考虑将其投入生产之前,他还有很长的路要走。

使用Deno中实现的模块的分散式方法旨在从集中式软件包存储库(如今为npm)中释放JavaScript生态系统。

Ryan Dahl表示,他希望在夏末发布Deno 1.0。 如果您对该项目的未来感兴趣,请注意它的存储库

亲爱的读者们! 您如何看待Deno?

Source: https://habr.com/ru/post/zh-CN460020/


All Articles