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.txt
和
hello2.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.json
和
node_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
需要
test
或
assertEqual
函数,则可以这样导入它们:
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?
