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内容索引(滚动到最后)
- Node.js与Deno的比较,并指导如何根据情况选择合适的工具
主要区别: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模块。因此,它假定:
- 文件结束
.cjs
使用CommonJS - 文件结束
.mjs
使用ES模块 - 文件结束
. 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.js
或deps.ts
:
// dps .js:模块依赖项//所有STD路径模块函数出口*作为路径从“https://deno.land/std@0.61.0 /道路/ mod.ts”;//一些STD datetime模块函数出口{parseDate,currentDayOfYear}从“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运行\——importmap=import_map.json\——不稳定\myscript.js
导入映射目前是一个不稳定的特性——不稳定
标志是必需的。该功能可能会在未来的Deno版本中更改。
调查的完整性
从URL引用的代码可能会在您不知情的情况下被更改或黑客攻击。知名网站因为直接链接到第三方客户端代码而遭到攻击。想象一下,如果一个脚本可以访问服务器资源,它会造成多大的损害。
Deno具有内置的安全性,因此执行脚本时必须带有诸如
——允许读
而且——allow-net
限制文件系统和网络访问。这将有助于防止一些问题,但它不能代替验证模块完整性!
Deno提供了完整性检查选项.如果你用的是单个依赖文件(如上所述):
// dps .js:模块依赖项//所有STD路径模块函数出口*作为路径从“https://deno.land/std@0.61.0 /道路/ mod.ts”;//一些STD datetime模块函数出口{parseDate,currentDayOfYear}从“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,包括:
- Skypack.dev
- jspm.org
- unpkg.com(添加一个
模块?
查询字符串到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介绍的最后更新的: