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 分钟前
【从0开始学前端】vue3简介、核心代码、生命周期
前端·vue.js·vue
simon_934929 分钟前
受够了压缩和收费?我作为一个码农,手撸了一款无限容量、原图直出的瀑布流相册!
前端
e***87701 小时前
windows配置永久路由
android·前端·后端
u***27611 小时前
TypeScript 与后端开发Node.js
javascript·typescript·node.js
星空的资源小屋1 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Dorcas_FE2 小时前
【tips】动态el-form-item中校验的注意点
前端·javascript·vue.js
小小前端要继续努力2 小时前
前端新人怎么更快的融入工作
前端
八月ouc2 小时前
解密JavaScript模块化演进:从IIFE到ES Module,深入理解现代前端工程化基石
javascript·es6·模块化·cmd·commonjs·amd·iife
四岁爱上了她2 小时前
input输入框焦点的获取和隐藏div,一个自定义的下拉选择
前端·javascript·vue.js
fouryears_234172 小时前
现代 Android 后台应用读取剪贴板最佳实践
android·前端·flutter·dart