NestJS小技巧33-在NestJs中识别循环依赖:使用madge

csharp 复制代码
by 雪隐 from https://juejin.cn/user/1433418895994094
文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可联系授权

原文链接

介绍

NestJS已经变成nodejs中最受欢迎的渐进式框架。Nodejs和其他库已经存在许多年了但是没有一个能够解决架构的问题。NestJS 提供了一个开箱即用的架构框架,对于那些熟悉 Angular 或 Java(Spring)概念的人来说可能会觉得很熟悉。如果您熟悉这些架构原则,那么您可能会发现 NestJS 的架构非常容易识别。

在NestJS中,概念叫做"providers"。这些providers能在框架中进行依赖注入,并且NestJS在运行时处理了链接过程。

循环依赖问题

如果Class A 需要导入 Class B与此同时Class B 需要Class A。

在NestJS的providers中循环依赖一般都会产生。或早或晚,当项目不断的壮大可能和一开始的时候的设想产生了偏差,人们往往会根据需要在任何地方定义功能,从而导致循环依赖。在NestJS中,这是一个最常见的问题。

当应用程序自我引导时,NestJs会抛出循环依赖的错误。

. . .

辨认循环依赖

在设计我们的代码库时,创建避免循环依赖的结构是至关重要的。然而,当应用程序扩展,跟踪各种实体之间的关系可能变得具有挑战性。

一个CLI名叫madge可以解决这个问题。

Madge是一个cli工具用来辨认各个文件中的依赖。它可以在cli中使用当然它可以生成一张可视图来告诉我们所有的依赖模型。

为了展示可视的依赖,我们可以使用graphviz

需要在本机安装

  • 对于MacOS,可以使用Homebrew:

    bash 复制代码
    brew install graphviz
  • 对于Ubuntu/Debian:

    bash 复制代码
    sudo apt-get install graphviz
  • 对于Windows,你可以从Graphviz的官方网站下载并安装:Graphviz Downloads

安装

bash 复制代码
npm install -D madge
npm install -D graphviz

生成依赖图

bash 复制代码
madge --image graph.png --extensions ts src

--image graph.png: 生成.png文件的依赖图

--extensions ts: 只查找在Typescript文件(.ts)中的依赖

src: 在。/src文件夹中查找,我们能够输入复数个文件夹。

上面的命令直接生成了依赖图。

如果您只想看循环依赖可以输入--circular作为参数

bash 复制代码
madge --image graph.png --extensions ts --circular src

蓝色告诉我们这些文件有依赖,绿色节点说明没有任何依赖,红色代表有循环依赖。

使用Graphviz(针对文件过多的大型应用程序)

bash 复制代码
madge --dot --extensions ts src > graph.gv

这会在当前文件夹下生成一个graph.gv文件

现在我能够复制和黏贴这些文件内容到网上进行分析或者您可以安装VSCode扩展用来预览您的.gv文件(打开vscode, 按 Ctrl+shift+p -> type -> graphivzpreview)

重构和解决

一旦我们找到了这些问题,我们能够重构我们的代码库来解决循环依赖。

  • 我们能够使用NestJS依赖注入(ForwardRef)来解决这个问题。
  • 我们可以重新组织我们的模块以区分关注点。
  • 创建共享模型来避免相互模型的依赖

总结

循环依赖通常发生在代码高度耦合的情况下。通过以前的经验,我已经看到,当我们尝试不重复代码(DRY原则)时,我们往往会遇到这种情况。

我们应该经常设计独立的核心服务,这些服务接受基本输入并返回一些DTOs。然后,我们应该在其他服务/控制器中协调它们,即使我们必须调用两个或更多的服务来获得最终输出。合并它们并创建另一个服务往往会导致问题。

如果出现循环依赖,我们应该考虑拆分代码,将代码移动到不同的特性模块中,并使用服务构建核心模块。如果两个模块中都使用了一个方法,看看我们是否可以将其移动到实用程序模块中。通常,我不建议创建一个通用的实用程序类,比如utils.js(创建特定的实用程序类,比如StringHelper.js, LeadDuplicateHelper.js)。

快乐编程 !! 干杯 👋

相关推荐
支支დ11 小时前
VO by Vercel 前端特定优势:为什么它是构建 AI 应用的新范式
前端·人工智能
香芋芋圆11 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF12 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿67412 小时前
vue3-async
前端·javascript·vue.js
YXWik612 小时前
记录前端请求接口在浏览器请求响应的Preview和Response展示的一样的问题
前端
2501_9289962212 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
东风破_12 小时前
从跨域到 WebSocket:前端跨域方案、SSE 与双向实时通信详解
前端·后端
原则猫13 小时前
TS 类型工具
前端
excel13 小时前
Nuxt + Twin CSS 中宽度超过屏幕时底部出现空白的原因与解决方案
前端·javascript
计算机魔术师15 小时前
美国司法部正式站队 OpenAI,AI 训练的版权账要这么算了
前端