Deno是一个类似于toNode的JavaScript和TypeScript运行时。js,基于Rust和V8 JavaScript引擎构建。它由Node的原始发明人瑞安·达尔(Ryan Dahl)创建。js,以弥补他最初设计和发布Node时所犯的错误。早在2009年。
瑞安';s对Node表示遗憾。js在他著名的';我后悔的十件事。js';2018年在JSConf欧盟大会上发表演讲。总而言之,他哀叹缺乏对安全性的关注,通过node#u模块的模块解析,以及浏览器与#39;除了其他的事情外,他还开始着手解决Deno中的所有这些错误。
在本文中,我们';我们将讨论为什么要创建Deno,以及它与Node相比的优缺点。js。它';我还将对Deno和#39;的怪癖和特点,这样你就可以决定它是否';It’这很适合你的下一个项目。
Deno作为一个独立的二进制文件分发,没有任何依赖关系。根据您的操作系统,您可以以各种方式安装Deno。最简单的方法是下载并执行shell脚本,如下所示:
#Linux和macOS$curl-fsSLhttps://deno.land/x/install/install.sh|sh#Windows PowerShell$iwrhttps://deno.land/x/install/install.ps1-useb | iex
一旦你';如果已经为您的操作系统执行了相应的命令,DenoCLI二进制文件将下载到您的计算机上。您可能需要将二进制位置添加到路径中,具体取决于您选择的安装方法。
在Bash中,可以通过将下面的行添加到$HOME/Bash_配置文件中来实现这一点。您可能需要启动一个新的shell会话,以使更改生效。
要验证Deno的安装版本,请运行以下命令。如果CLI下载成功并添加到您的路径中,它应该将Deno版本打印到控制台。
如果您的Deno版本过时,可以通过upgrade子命令升级到最新版本:
$deno升级查找最新版本发现最新版本1.14.2正在检查https://github.com/denoland/deno/releases/download/v1.14.2/deno-x86_64-unknown-linux-gnu.zip31.5 MiB/31.5 MiB(100.0%)Deno正在升级到1.14.2版存档:/tmp/。tmpfdtMXE/deno。拉链充气:deno升级成功
继续写一个习惯性的hello world程序来验证一切是否正常。您可以为Deno程序创建一个目录,并将以下代码放入索引中。ts文件位于目录';它的根。
通过向run子命令提供文件名作为参数来保存和执行文件。如果文本为";你好,德诺" 输出,这意味着您已经正确安装和设置了Deno。
要了解Deno CLI提供的其他功能和选项,请使用--help标志:
Deno over Node的一大卖点。js是其对TypeScript的一流支持。
作为你';我已经看过了,你不';除了安装Deno CLI,不需要做任何事情。与它的前身一样,Deno使用V8运行时引擎来解析和执行JavaScript代码,但它也在可执行文件中包含TypeScriptcompiler,以实现对EtypeScript的支持。
在引擎盖下,检查并编译打字脚本代码。结果JavaScript代码缓存在文件系统的一个目录中,可以在不从头编译的情况下再次执行。您可以使用deno info检查缓存目录和包含deno托管文件的其他目录的位置。
Deno不需要任何配置来使用TypeScript,但是如果您想调整TypeScript编译器解析代码的方式,可以提供一个配置。您可以提供一个JSON文件来指定TypeScript编译器选项。尽管如此。json是使用独立编译器时的惯例,Deno团队建议使用Deno。json,因为其他特定于Deno的配置选项可以放在那里。
请注意,Deno没有';不支持所有类型脚本编译器选项。DENO文档中提供了可用选项的完整列表及其默认值。这里';这是Deno的一个示例配置文件:
在撰写本文时,Deno不会自动检测到Deno。json文件必须通过--config标志指定。不过,该功能计划在未来发布。
当Deno CLI遇到类型错误时,它会停止脚本的编译,并以非零退出代码终止。您可以通过以下方式绕过该错误:
Deno还提供了一个--no check标志来禁用类型checkingaltogether。这有助于防止TypeScript编译器在快速迭代问题时拖慢您的速度。
Deno为自己是JavaScript和TypeScript的安全运行时而自豪。它维护安全的部分方式是通过许可证系统。要演示权限在Deno中的工作方式,请将下面的脚本添加到索引中。ts文件。它';这是一个从疾病中获取最新全球新冠肺炎统计数据的脚本。嘘。
异步函数getCovidStats(){try{const response=await fetch(";https://disease.sh/v3/covid-19/all" ); const data=等待响应。json();安慰表(数据);}catch(err){console.error(err);}getCovidStats();
$deno运行索引。ts许可被拒绝:需要访问";病sh",使用--allow net标志再次运行
上面的错误消息表明脚本没有';我没有被授予网络访问权。它建议在命令togrant access中包含--allow net标志。
$deno run——允许净索引。ts┌────────────────────────┬───────────────┐ │ (idx)│ 价值观│ ├────────────────────────┼───────────────┤ │ 更新│ 1633335683059│ │ 案例│ 235736138│ │ 今天的案子│ 32766│ │ 死亡│ 4816283│ │ 今天的死亡人数│ 670│ │ 恢复│ 212616434│ │ 今天康复了│ 51546│ │ 忙碌的│ 18303421│ │ 批评的│ 86856│ │ 凯斯伯伦埃米利昂│ 30243│ │ 死亡之狮│ 617.9│ │ 测验│ 3716763329│ │ Testsperonemilion│ 473234.63│ │ 人口│ 7853954694│ │ 每人一箱│ 0│ │ 一人一死│ 0│ │ 一人一人│ 0│ │ 百万│ 2330.47│ │ 回收的百万│ 27071.26│ │ 临界百万│ 11.06│ │ 受影响国家│ 223│ └────────────────────────┴───────────────┘
您可以提供一个由逗号分隔的主机名或IP地址组成的allowlist,作为--allow net的参数,这样脚本就只能访问指定的网站,而不是授予脚本访问所有网站的全面批准(如shownabove所示)。如果脚本试图连接到allowlist中不存在的域,Deno将阻止它连接,脚本执行将失败。
这是Deno';这是对节点的改进。任何脚本都可以通过网络访问任何资源。对文件系统的读写也存在类似的权限。如果脚本需要执行任一任务,则需要分别指定--allow read和--allow write权限。这两个标志都允许您设置脚本可访问的特定目录,以便文件系统的其他部分不受篡改。Deno还提供了一个--allow all标志,如果需要的话,它可以为脚本启用所有安全敏感函数。
其中一个是Deno';它的主要目标是尽可能与网络浏览器兼容。这反映在它使用web平台API,而不是为某些操作创建特定于Deno的API。例如,我们在上一节中看到了FetchAPI的运行。这正是浏览器中使用的Fetch API,在需要考虑Deno中独特的安全模型时有一些偏差(这些更改大多无关紧要)。
Deno管理依赖关系的方式可能是它与Node显著不同的最明显的方式。js。
节点。js使用包管理器(如npm或Thread)将第三方包从npmregistry下载到node_modules目录和包中。用于跟踪项目的json文件';它的依赖性。Deno摒弃了这些机制,支持以浏览器为中心的第三方软件包使用方式:URL。
这里';这是一个使用Deno的web应用程序框架Oak创建基本web服务器的示例:
从"导入{Application};https://deno.land/x/oak/mod.ts" ; const app=新应用程序();应用程序。使用((ctx)=>;{ctx.response.body=";Hello Deno!";});应用程序。addEventListener(";listen";,({hostname,port,secure})=>;{console.log(`监听:http://localhost:${port}`;});等待应用程序。收听({port:8000});
Deno使用ES模块,与web浏览器中使用的模块系统相同。只要引用的脚本导出方法或其他值,就可以从绝对或相对路径导入Amodule。它';值得注意的是,无论是从绝对路径还是相对路径导入,文件扩展名都必须始终存在。
虽然您可以从任何URL导入模块,但许多专门为Deno构建的第三方模块都是通过Deno缓存的。land/x。每次删除模块的新版本时,它都会自动缓存在该位置,并使其不可变,以便特定版本模块的内容保持不变。
假设您运行了前面代码段中的代码。在这种情况下,它将下载模块及其所有依赖项,并将它们本地缓存在由DENO_DIR环境变量指定的目录中(默认值应为$HOME/.cache/DENO)。下次程序运行时,将不会下载,因为所有依赖项都已在本地缓存。这与Gomodule系统的工作原理类似。
$deno run——允许净索引。ts下载https://deno.land/x/oak/mod.ts使用最新版本(v9.0.1)隐式警告https://deno.land/x/oak/mod.ts下载https://deno.land/x/oak@v9。0.1/模。ts。
对于生产应用程序,Deno的创建者建议通过将依赖项检查到源代码管理中来提供依赖项,以确保连续可用性(即使模块的源代码不可用,无论出于何种原因)。将DENO_DIR环境变量指向项目中的本地目录(例如供应商),您可以将其提交给它。
例如,下面的命令将下载所有脚本';将依赖项添加到项目中的供应商目录中。随后,您可以提交文件夹,以便在生产服务器中一次将其全部删除。你';ll还需要将DENO_DIR变量设置为从服务器上的供应商目录中读取,而不是重新下载。
$DENO_DIR=$PWD/供应商DENO缓存索引。ts#Linux和macOS$$env:DENO#u DIR="$(获取位置)\vendor";deno缓存索引。ts#Windows PowerShell
Deno还支持对依赖项进行版本控制的概念,以确保可生成的构建。目前,我们';我从美国进口橡木https://deno.land/x/oak/mod.ts.它总是下载最新版本,将来可能会与您的程序不兼容。当您第一次下载模块时,它还会导致出现警告:
如果你';在代码库中的许多文件中重新引用一个模块,升级它可能会变得单调乏味,因为您必须在许多地方更新URL。为了避免这个问题,Deno团队建议在一个集中的deps中导入外部依赖项。ts文件,然后重新导出它们。这里';这是一个样本。ts文件,用于从Oak库导出所需内容。
此时,更新一个模块就变成了在deps中更改URL的简单问题。ts文件指向新版本。
Deno提供了一个标准图书馆(stdlib),旨在成为Go和#39的自由港;s标准图书馆。标准库中包含的模块由Deno团队审核,并随Deno的每次发布而更新。提供stdlib的目的是允许您立即创建有用的web应用程序,而无需求助于任何第三方软件包(这是Node.js生态系统中的标准)。
编码:提供帮助来处理各种文件格式,如XML、CSV、base64、YAML、二进制等。
这里';这是一个使用Deno';s stdlib创建基本web服务器:
从"导入{listendserve};https://deno.land/[email protected]/http/server。ts";const addr=";:8080" ; 常量处理程序=(请求:请求):响应=>;{let body=";您的用户代理是:\n\n";body+=request.headers.get(";用户代理";)|"未知";返回新的响应(body,{status:200});};安慰日志(`HTTP Web服务器正在运行。请访问:http://localhost:8080/` ); 等待列表并服务(地址、处理程序);
请注意,标准库中的模块当前标记为不稳定(如版本号所示)。这意味着您不应该在正式的生产应用程序中依赖它们。
不可否认的一个主要原因是。js之所以成功,是因为在一个项目中可以下载和使用大量软件包。如果你';如果你正在考虑改用Deno,你可能会想知道你是否';我不得不放弃所有你知道和喜欢的NPM套餐。
简单的回答是:不。但是如果依赖节点,您可能无法在Deno中使用一些NPM包。js API(尤其是在Deno';s Node.js兼容层不支持特定API的情况下),许多NPM包可以通过esm等CDN在Deno中使用。sh和skypack。开发人员:这两个CDN都将NPM包作为ES模块提供,即使包的作者没有专门针对Deno进行设计,也可以在Deno脚本中使用这些模块。
要确保Deno能够发现与包关联的类型,请确保添加?使用Skypack时,在程序包URL末尾添加dts后缀';s CDN。这会导致Skypack设置一个X-TypeScript-Types头,这样Deno就可以自动发现与包关联的类型。Esm。默认情况下,shin包含此标题,但您可以通过添加?在包URL的末尾没有checksuffix。
Deno CLI附带了几个有价值的工具,使开发人员的体验更加愉快。比如节点。js,它附带了一个REPL(Read Evaluate PrintLoop),您可以使用deno REPL访问它。
它还有一个内置的FileWatcher,可以与它的几个子命令一起使用。例如,您可以通过使用--watch标志将deno run配置为在文件更改后自动重建并重新启动程序。在节点中。这个功能通常是通过一些第三方软件包实现的,比如nodemon。
$deno run——允许净——观察索引。ts HTTP Web服务器正在运行。请访问:http://localhost:8080/检测到监视程序文件更改!重启!HTTP Web服务器正在运行。请访问:http://localhost:8080/
使用Deno 1.6,您可以将脚本编译为自包含的可执行文件,而不需要通过compile子命令安装Deno(您可以在Node.js中使用pkg执行相同的操作)。还可以通过--target标志为其他平台生成可执行文件(交叉编译)。编译脚本时,必须指定运行脚本所需的权限。
请注意,通过这个过程产生的二进制文件非常庞大。在我的测试中,deno compile为一个简单的"生成了一个83MB的二进制文件;你好世界";程序然而,Deno团队目前正在研究一种方法,将文件大小减少到更易于管理的程度。
分发Deno程序的另一种方法是通过bundle子命令将其打包成单个JavaScript文件。该文件包含程序的源代码及其所有依赖项,可以通过deno run执行,如下所示。
$deno bundle索引。ts索引。捆js支票file:///home/ayo/dev/demo/deno/index.js捆file:///home/ayo/dev/demo/deno/index.js排放";指数捆js";(7.39KB)$deno run——允许使用净索引。捆js HTTP Web服务器正在运行。请访问:http://localhost:8080/
Deno附带的另外两个很棒的工具是内置linter(Deno-lint)和formatter(Deno-fmt)。在节点中。js生态系统、linting和格式化代码通常分别使用ESLint和Prettier处理。
使用Deno时,您不再需要安装任何东西或编写配置文件来获取JavaScript、TypeScript和其他支持的文件格式的linting和格式化。
JavaScript和TypeScript代码都内置了对单元测试的支持。当您运行deno测试时,它会自动检测以_test结尾的任何文件。ts或。测验ts(也支持其他文件扩展名)并执行其中定义的任何测试。
要编写第一个测试,请创建一个索引测试。ts文件,并用以下代码填充它:
从"导入{assertEquals};https://deno.land/[email protected]/测试/断言。ts";德诺。测试(";乘以两个数字";,()=>;{const ans=2*2;assertEquals(ans,4);});
Deno提供了Deno。创建单元测试的测试方法。它将测试的名称作为第一个参数。它的第二个参数是测试运行时执行的函数。
还有第二种风格是用一个object代替两个参数。它支持测试名称和函数的其他属性,以配置测试是否运行或如何运行。
德诺。测试({name:";乘以两个数字";,fn(){const ans=2*2;assertEquals(ans,4);},});
assertEquals()方法来自standardlibrary中的测试模块,它提供了一种轻松检查两个值相等的方法。
$deno测试将两个数字相乘。。。正常(8ms)测试结果:正常。1人通过;0次失败;0被忽略;测量0;0过滤掉(37毫秒)
选择编程语言或环境的主要考虑因素之一是它与编辑器和IDE的集成。在Deno 1.6中,向运行时添加了内置语言服务器(Deno lsp),以提供以下功能:
以及支持语言服务器协议(LSP)的任何编辑器的其他语言智能。您可以在Deno';这是在线医生。
在本文中,我们';我考虑了Deno运行时的许多方面,以及它的运行方式';这是通过节点进行的升级。js。
关于Deno及其生态系统还有很多要说的,但这应该是对Node的有益介绍。js开发人员正在考虑一个新项目的Deno。Deno第三方软件包的可用性较低是一个明显的不足之处,因为它';它不像Node那样经过战斗考验。由于年轻,js在现实世界中很受欢迎(Deno 1.0于2020年5月发布)。
比较节点之间的性能。js和Deno表明他们';在大多数情况下,我们都在同一个大概范围内,尽管这里有一个较少的节点。js表现出了卓越的性能。随着Deno变得更加成熟,测量的差异必然会改善。
在决定节点之间的连接时。js和Deno,it';记住,Deno提供的一些好处也可以带给Node,这一点也很重要。在第三方软件包的帮助下。所以,如果你对Deno只有一两件事是钦佩的,那么你很可能';我们将能够在inNode上实现类似的结果。js,尽管没有那么完美。
另外,如果你喜欢这篇文章,请订阅我们的JavaScript魔法列表,每月深入了解更多神奇的JavaScript技巧。
P.P.S.如果您的节点需要APM。js应用程序,去查看AppSignal APM for Node。js。