Deno模块:使用,最佳实践和节点模块导入

克雷格的盾牌
分享

了解Deno模块-如果你来自Node.js,你会遇到的最大的工作流变化。了解它们是如何工作的以及如何最好地使用它们,如何在Deno中使用Node.js模块和npm包,等等。

node . js是一个基于Chrome V8引擎的JavaScript运行时,由Ryan Dahl开发,于2009年发布。

Deno是一个基于Chrome V8引擎的JavaScript运行时,由Ryan Dahl开发,于2020年发布。它的诞生得益于10年的后见之明。这并不一定使它成为Node.js的续集或更优秀的版本,但它偏离了这条路径。

参见:

主要区别:Deno原生支持TypeScript、安全性、测试和浏览器api。模块处理较少受到关注,但它可能是创建JavaScript应用程序的最大变化。在讨论Deno之前,让我带你回到一个更简单的时代……

node . js模块

JavaScript在2009年还没有标准的模块系统。这部分是因为它的浏览器传统,而ES6 / ES2015是几年之后的事情。

Node.js不提供模块是不可想象的,所以它从社区解决方案中选择了CommonJS。这导致了节点包管理器的开发npm,它允许开发人员轻松地搜索、使用和发布他们自己的JavaScript模块。

NPM的使用呈指数增长。它已经成为有史以来最受欢迎的包管理器,到2020年年中,托管了近150万个模块,每天发布超过800个新模块(来源:modulecounts.com).

Deno模块

Deno选择ES2015模块进口从绝对或相对URL:

进口某物“https://somewhere.com/somehow.js”

该URL处的脚本必须出口函数或其他相应的值,例如。

出口函数某物控制台日志“某事被执行了”

Deno使用与现代web浏览器相同的模块系统。

Node.js也支持ES2015模块但它很复杂,还处于实验阶段。CommonJS和ES2015模块看起来很相似,但工作方式不同:

  • CommonJS在执行代码时按需从文件系统加载依赖项。
  • ES模块从url预解析,以便在执行代码之前解析进一步的导入。

Node.js必须继续支持CommonJS以及处理混合ES模块。因此,它假定:

  1. 文件结束.cjs使用CommonJS
  2. 文件结束.mjs使用ES模块
  3. 文件结束. js是CommonJS除非最接近的package.json“类型”:“模块”节点使用——输入类型=模块选择。

可以理解为什么Deno选择单一标准模块系统。然而,npm是Node成功的关键,所以发现Deno取消了它是令人惊讶的。

没有包管理器。

对npm的一个批评是每个项目的庞大规模node_modules目录中。它可以达到数百兆字节,因为模块需要其他模块的特定版本。

节点模块质量

当脚本中第一次遇到模块的URL时,Deno将其下载并缓存到全局目录中。因此,无论有多少项目引用它,都只需要特定模块版本的单个副本。

我知道你们在想:“啊,但是如果……”

但是Deno有解决模块url引起的问题的选项。

不可靠的网址

url可能会暂时失效、更改或永远消失。这对任何包管理器都是一个问题,npm在过去也遇到过问题(它也允许从URL安装).

对于任务关键型Node.js应用程序,建议添加您的node_modules目录到项目的Git/其他存储库。

Deno也支持类似的选项。您可以设置DENO_DIR环境变量到当前项目中的目录路径,例如:

DENO_DIR~ / myproject / deno_modules '

在Windows中cmd使用:

>DENO_DIR“C: \ myproject \ deno_modules”

或Windows Powershell:

>env美元: DENO_DIR“C: \ myproject \ deno_modules”

当应用程序运行时,Deno会将模块缓存到该目录,以便将它们添加到项目的源代码控制存储库中。

您还可以考虑将依赖项捆绑到单个JavaScript或TypeScript文件中。的Deno包的命令可以在一个步骤做到这一点:

Deno bundle myscript.js

在哪里myscript.js输入脚本是否正常执行deno运行.由此产生的自成体系myscript.bundle.js文件可以部署到活动服务器。

与顶级等待绑定

Deno支持顶级等待没有必要包装等待匿名电话异步函数。不幸的是,顶层等待绑定失败因此必须添加包装器函数。这是一个已知的问题,将在未来的版本中修复。

最后:小心不寻常的url上的随机Deno模块!Deno、Github或Bitbucket的URL有良好的文档和社区输入通常会更安全。

模块版本

理想情况下,模块url应该有版本控制,这样就可以引用特定的代码版本。例如,Deno标准库允许您加载HTTP服务器模块的特定版本

进口服务“https://deno.land/std@0.61.0 http / server.ts”

可以引用主分支而不是:

进口服务“https://deno.land/std/http/server.ts”

但这将下载最新版本,未来的版本可能与您的应用程序不兼容。

您可以使用类似的版本控制约定在自己的服务器上发布Deno模块,但随着它的流行,您的站点可能会收到大量流量。更健壮的方法是在服务上使用存储库,例如GitHub并为每个版本分配一个git标记。服务包括denopkg.com而且unpkg.com可以用来提供一个公开版本的模块URL。

多个模块提到

您可能需要在整个应用程序代码库的许多文件中引用相同的模块URL。当您想要更新该模块时,URL需要在多个地方更改。搜索和替换是可行的,但它很笨拙,容易出错,并且增加了合并冲突的机会。

或者,您可以使用单个依赖项文件导入项目中使用的每个模块。它通常被命名为deps.jsdeps.ts

// dps .js:模块依赖项//所有STD路径模块函数出口作为路径“https://deno.land/std@0.61.0 /道路/ mod.ts”//一些STD datetime模块函数出口parseDatecurrentDayOfYear“https://deno.land/std@0.61.0 datetime mod.ts”

然后可以引用Deno模块deps.js在任何其他项目文件:

进口路径currentDayOfYear”。/ deps.js '控制台日志路径9月控制台日志currentDayOfYear

您只需要更改一个URL引用deps.js当模块更新时。

另一种选择是导入映射。这是一个小的JSON文件,通常命名为import_map.json,它为完整或部分URL分配一个名称:

“进口”“路径/”“https://deno.land/std@0.61.0 /道路/”“datetime /”“https://deno.land/std@0.61.0 / datetime /”

你可以在任何脚本中引用导入映射名:

进口作为路径“路径/ mod.ts”进口currentDayOfYear“datetime / mod.ts”控制台日志路径9月控制台日志currentDayOfYear

在执行应用程序时导入JSON文件deno运行

deno运行——importmapimport_map.json——不稳定myscript.js

导入映射目前是一个不稳定的特性——不稳定标志是必需的。该功能可能会在未来的Deno版本中更改。

调查的完整性

从URL引用的代码可能会在您不知情的情况下被更改或黑客攻击。知名网站因为直接链接到第三方客户端代码而遭到攻击。想象一下,如果一个脚本可以访问服务器资源,它会造成多大的损害。

Deno具有内置的安全性,因此执行脚本时必须带有诸如——允许读而且——allow-net限制文件系统和网络访问。这将有助于防止一些问题,但它不能代替验证模块完整性!

Deno提供了完整性检查选项.如果你用的是单个依赖文件(如上所述)

// dps .js:模块依赖项//所有STD路径模块函数出口作为路径“https://deno.land/std@0.61.0 /道路/ mod.ts”//一些STD datetime模块函数出口parseDatecurrentDayOfYear“https://deno.land/std@0.61.0 datetime mod.ts”

以下deno命令生成lock.json包含所有导入的Deno模块校验和的文件:

Deno缓存——锁lock.json--lock-write deps.js

当另一个开发人员克隆你的项目时,他们可以重新加载每个模块,并验证每个模块的完整性,以确保它们与你的完全相同:

Deno缓存—重载—锁定lock.jsondeps.js

Deno并不强制执行完整性检查。最好将这些进程作为自动化的Git钩子或类似的方式运行。

使用Node.js模块

许多Node.js api已经为Deno - see复制deno.land / std /节点.这不是一个完整的列表,但是您可以找到常见的文件、事件、缓冲区和实用程序模块。

这里提供了近800个第三方Deno模块deno.land / x.有类似express .js的框架、数据库驱动程序、加密函数、命令行工具等等。

您还将发现流行模块的精选列表,例如很棒的Deno

然而,你五月可以导入150万个Node.js模块中的任何一个。一些cdn可以将npm/CommonJS包转换为ES2015模块的url,包括:

您需要的模块在Deno中是否正常工作是另一回事。

幸运的是,随着JavaScript运行时生态系统的发展,不需要特殊处理就可以在Node.js和Deno上工作的跨平台模块可能会出现。

更多模块事项

引用模块url是有争议的,对于那些来自非常流行的npm的人来说可能会感到不安。也就是说,Deno简化了JavaScript模块的使用。它解决了一些npm的批评,同时减轻了ES2015模块的许多潜在副作用。

但它还远远不够完美。

发布npm模块是一种轻松的搜索过程npmjs.com很简单。您的搜索词可能会返回500个结果,但是通过对软件包进行排序,可以将选择瘫痪最小化知名度、质量和维护的因素。

向Deno 's提交代码第三方模块列表更困难。模块必须通过自动化测试,但不能保证质量,搜索结果是按字母顺序排序的。现有的系统一旦达到几千个模块就不太可能持续下去。

在npm中更新包也很容易。你可以跑npm过时查看更新列表或npm安装更宽松的版本号引用于package.json

在Deno中没有等效的更新检查选项。类似包管理器的项目包括Trex更新Deno依赖关系,deno-check-updates但这些往往取决于导入地图并且总是依赖于有语义版本的url。

你应该换成迪诺吗?

Node.js还没有死。它很成熟,在运行时背后有十年的模块、技术、文档和经验。

Deno利用了很多这些知识,但它是非常新的,并将在未来几年迅速发展。现在就把Deno押在大型应用上可能还为时过早,但小型项目的风险较小。那些已经使用TypeScript或来自其他语言的人可能会享受更简单的体验,但Node.js开发人员在转换到Deno和再转换回来时不会有任何困难。

然而,Deno有一个有趣的好处:

  • 它的模块系统与客户端JavaScript完全相同
  • 它实现了很多浏览器api:你可以引用一个窗口对象、设置事件监听器、启动Web worker、使用Fetch() API发出远程服务器请求等等。

可以在客户端或服务器上工作的同构JavaScript库的梦想已经向前迈出了重要的一步。

Deno基金会

跟上德诺的步伐。我们的Deno基金会系列可以帮助您迈出进入Deno世界和超越的第一步,我们还在不断添加。我们将为您带来成为专业人士所需的教程。您可以随时参考我们的索引,因为它是在我们的Deno介绍的最后更新的:

Deno基金会

Baidu