首页 > web前端 > js教程 > DENO模块:用法,最佳实践和节点模块导入

DENO模块:用法,最佳实践和节点模块导入

Joseph Gordon-Levitt
发布: 2025-02-12 08:33:10
原创
617 人浏览过

Deno Modules: Usage, Best Practices & Node Module Imports

深入了解Deno模块——如果您来自Node.js,这将是您遇到的最大工作流程变化。了解它们的工作原理以及最佳使用方法,如何在Deno中使用Node.js模块和npm包等等。

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

Deno也是一个基于Chrome V8引擎的JavaScript运行时,由Ryan Dahl开发,于2020年发布。它是在十年的经验积累的基础上创建的。这并不一定意味着它是Node.js的续集或更高级的替代品,但它确实偏离了Node.js的路径。

另见:

  • 我们的Deno指南,包括我们的Deno内容索引(滚动到结尾)
  • Node.js与Deno的比较,以及选择适合特定情况的工具指南

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

关键要点

  • Deno是一个基于Chrome V8引擎的JavaScript运行时,它通过原生支持TypeScript、安全性、测试和浏览器API而偏离了Node.js。它还选择使用ES2015模块,这些模块从绝对或相对URL导入,这与使用CommonJS的Node.js不同。
  • Deno没有像Node.js中的npm那样的包管理器。相反,它在脚本中第一次遇到模块的URL时,就会下载并将其缓存到全局目录中,这意味着无论有多少项目引用它,只需要一个特定模块版本的副本。
  • Deno允许对模块URL进行版本控制,以便可以引用特定的代码版本。它还支持使用单个依赖项文件导入项目中使用的每个模块,或者使用导入映射将名称分配给完整或部分URL。
  • 该平台具有内置安全性,限制文件系统和网络访问,并提供完整性检查选项。它还支持使用Node.js API和跨平台模块,这些模块无需特殊处理即可在Node.js和Deno上运行,并且随着JavaScript运行时生态系统的不断发展,这类模块可能会变得越来越普遍。

Node.js模块

2009年,JavaScript没有标准的模块系统。部分原因是它的浏览器背景,ES6/ES2015还要几年时间才会出现。

Node.js如果不提供模块是不可想象的,因此它从社区的几种变通方案中采用了CommonJS。这导致了Node包管理器(npm)的开发,它允许开发人员轻松搜索、使用和发布他们自己的JavaScript模块。

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

Deno模块

Deno选择使用ES2015模块,您可以从绝对或相对URL导入这些模块:

<code>import { something } from 'https://somewhere.com/somehow.js';
</code>
登录后复制
登录后复制
登录后复制

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

<code>export function something() {
  console.log('something was executed');
}
</code>
登录后复制
登录后复制
登录后复制

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设置了"type": "module",或者node是用--input-type=module选项执行的。

可以理解为什么Deno选择单一的标准模块系统。但是,npm是Node成功的重要因素,因此令人惊讶的是Deno取消了它。

没有包管理器。

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

Deno Modules: Usage, Best Practices & Node Module Imports

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

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

……但是Deno有解决模块URL提出的问题的选项。

不可靠的URL

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

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

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

<code>DENO_DIR=~/myproject/deno_modules`
</code>
登录后复制
登录后复制

在Windows cmd中使用:

<code>> set DENO_DIR="C:\myproject\deno_modules"
</code>
登录后复制
登录后复制

或Windows Powershell:

<code>> $env:DENO_DIR="C:\myproject\deno_modules"
</code>
登录后复制
登录后复制

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

您还可以考虑将依赖项捆绑到单个JavaScript或TypeScript文件中。Deno bundle命令可以一步完成此操作:

<code>deno bundle myscript.js myscript.bundle.js</code>
登录后复制
登录后复制

其中myscript.js是通常使用deno run执行的入口脚本。生成的独立myscript.bundle.js文件可以部署到实时服务器。

使用顶级await进行捆绑

Deno支持顶级await:无需将await调用包装在匿名async函数中。不幸的是,顶级await在捆绑中失败,因此必须添加包装函数。这是一个已知问题,将在未来的版本中修复。

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

模块版本控制

理想情况下,模块URL应该进行版本控制,以便您可以引用特定的代码版本。例如,Deno标准库允许您加载HTTP服务器模块的特定版本:

<code>import { something } from 'https://somewhere.com/somehow.js';
</code>
登录后复制
登录后复制
登录后复制

也可以引用master分支:

<code>export function something() {
  console.log('something was executed');
}
</code>
登录后复制
登录后复制
登录后复制

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

可以使用类似的版本控制约定在您自己的服务器上发布Deno模块,但是随着它的流行,您的网站可能会收到大量流量。更可靠的方法是使用GitHub等服务的存储库,并为每个版本分配一个git标签。denopkg.com和unpkg.com等服务可用于提供公开版本化的模块URL。

多个模块提及

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

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

<code>DENO_DIR=~/myproject/deno_modules`
</code>
登录后复制
登录后复制

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

<code>> set DENO_DIR="C:\myproject\deno_modules"
</code>
登录后复制
登录后复制

当模块更新时,您只需要更改deps.js中的单个URL引用。

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

<code>> $env:DENO_DIR="C:\myproject\deno_modules"
</code>
登录后复制
登录后复制

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

<code>deno bundle myscript.js myscript.bundle.js</code>
登录后复制
登录后复制

然后,使用deno run执行应用程序时,导入JSON文件:

<code>import { serve } from 'https://deno.land/std@0.61.0/http/server.ts';
</code>
登录后复制

导入映射目前是一个不稳定的功能,因此需要--unstable标志。该功能可能会在未来的Deno版本中发生变化。

调查完整性

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

Deno具有内置安全性,因此脚本必须使用--allow-read和--allow-net等标志执行,以限制文件系统和网络访问。这将有助于防止一些问题,但这不能替代验证模块完整性!

Deno提供了一个完整性检查选项。如果您使用单个依赖项文件(如上所述),则最容易:

<code>import { serve } from 'https://deno.land/std/http/server.ts';
</code>
登录后复制

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

<code>import { something } from 'https://somewhere.com/somehow.js';
</code>
登录后复制
登录后复制
登录后复制

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

<code>export function something() {
  console.log('something was executed');
}
</code>
登录后复制
登录后复制
登录后复制

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

使用Node.js模块

许多Node.js API都已为Deno复制——参见deno.land/std/node。这不是一个完整的列表,但您会发现常见的文件、事件、缓冲区和实用程序模块。

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

您还会发现流行模块的精选列表,例如Awesome Deno。

但是,您可能能够导入150万个Node.js模块中的任何一个。几个CDN可以将npm/CommonJS包转换为ES2015模块URL,包括:

  • Skypack.dev
  • jspm.org
  • unpkg.com (在URL中添加?module查询字符串)

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

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

更多模块问题

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

但这远非完美。

发布npm模块很容易,搜索npmjs.com也很简单。您的搜索词可能会返回500个结果,但通过按流行度、质量和维护因素对包进行排名,可以最大限度地减少选择瘫痪。

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

在npm中更新包也很容易。您可以运行npm outdated查看更新列表,或者在package.json中引用较宽松的版本号时,只需运行npm install。

Deno中没有等效的更新检查选项。有可用的类似包管理器的项目,包括Trex、Update Deno Dependencies和deno-check-updates,但这些项目通常依赖于导入映射,并且始终依赖于语义版本化的URL。

您应该切换到Deno吗?

Node.js并没有消亡。它已经成熟,并且拥有十年的模块、技术、文档和运行时经验。

Deno利用了这些知识中的大部分,但它非常新,并且在未来几年会快速发展。对于大型应用程序来说,现在可能还为时过早,但对于小型项目来说,风险较小。那些已经使用TypeScript或来自其他语言的人可能会享受更轻松的体验,但Node.js开发人员不会有任何困难来转换到Deno然后再转换回来。

但是,Deno有一个有趣的优势:

  • 它的模块系统与客户端JavaScript相同
  • 它正在实现许多浏览器API:您可以引用window对象、设置事件侦听器、启动Web Workers、使用Fetch() API发出远程服务器请求等等。

在客户端或服务器上都能工作的同构JavaScript库的梦想向前迈进了一大步。

Deno基础

快速了解Deno。我们的Deno基础集合帮助您迈出进入Deno世界及其他领域的第一步,并且我们不断地向其中添加内容。我们将为您提供成为专业人士所需的教程。您始终可以在我们的Deno入门指南结尾处更新索引:

➤ Deno基础

关于Deno模块的常见问题

什么是Deno模块?Deno模块是Deno中的代码单元,Deno是JavaScript和TypeScript的安全运行时。Deno中的模块类似于Node.js中的CommonJS模块和现代JavaScript中的ES6模块。它们使开发人员能够通过将代码分解成可重用和封装的块来组织和共享代码。

如何在Deno中创建模块?在Deno中创建模块很简单。您可以创建一个新文件(例如,module.ts),定义您的函数或类,然后使用export关键字导出它们。其他Deno脚本可以导入和使用这些模块。

如何在Deno中导入模块?要在Deno中导入模块,您可以使用import关键字后跟模块的路径或URL。Deno支持本地和远程导入。

我可以在Deno中使用第三方模块吗?是的,Deno支持直接从URL导入模块,允许您使用托管在包注册表或GitHub存储库上的第三方模块。

以上是DENO模块:用法,最佳实践和节点模块导入的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板