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)。

快乐编程 !! 干杯 👋

相关推荐
To_OC1 小时前
写了三遍 Todo List,我终于搞懂了 React 父子组件到底怎么通信
前端·javascript·react.js
勇往直前plus2 小时前
Vue3(篇一) 核心概念——响应式模板语法与组件基础
前端·javascript·vue.js
咩咩啃树皮2 小时前
第43篇:Vue3计算属性(computed)完全精讲——缓存机制、依赖计算、业务最优解
前端·vue.js·缓存
用户938515635073 小时前
从零搭建 AI 日记助手:用 Milvus 向量数据库 + RAG 让机器读懂你的每一天
javascript·人工智能·全栈
徐小夕4 小时前
花了一周,3亿tokens,我开源了一款 Word 文档智能审查平台,文稿自动质检+可视化分析,告别低效人工审核
前端·算法·github
a1117764 小时前
坦克大战3D Three.js 3D (开源项目)
开发语言·javascript·3d
kyriewen5 小时前
别再乱用useEffect了——你写的10个里有8个不该存在
前端·javascript·react.js
Ivanqhz5 小时前
Rust &‘static str浅析
java·前端·javascript·rust
IT_陈寒6 小时前
SpringBoot这个分页坑,我踩了三天才爬出来
前端·人工智能·后端
颜酱6 小时前
05 | 召回前置准备:根据业务数据库生成各数据库(读取配置阶段)
前端·人工智能·后端