NestJS 的模块系统提供了一种组织应用程序组件和管理依赖关系的结构化方式。它是组织 NestJS 应用程序代码的基础构建块。本文档涵盖了模块架构、注册过程以及模块如何通过依赖注入系统进行交互。有关整体依赖注入系统的信息,请参阅 2.1。
NestJS 中的模块封装了相关代码,例如提供者(服务、存储库、工厂等)和控制器,这有助于开发人员保持清晰的应用程序结构以及应用程序不同部分之间的清晰边界。
来源: packages/core/injector/module.ts44-675
NestJS 中的模块是一个带有所装饰的类 @Module()。模块装饰器接受一个描述模块组件的元数据对象。
模块类本身维护着这些组件的集合。
来源: packages/core/injector/module.ts44-176
提供者是您的应用程序所需的任何可注入类或值,例如服务、存储库、工厂等。模块类使用注入标记作为键,将提供者存储在 Map 中。
来源: packages/core/injector/module.ts244-285
控制器处理传入的请求并将响应返回给客户端。它们也作为 InstanceWrappers 存储在 Map 中。
来源: packages/core/injector/module.ts503-519
导入定义了此模块所依赖的其他模块。导入存储为模块实例的 Set。
来源: packages/core/injector/module.ts530-532
导出定义了此模块中的哪些提供者应提供给导入此模块的其他模块。导出存储为注入标记的 Set。
来源: packages/core/injector/module.ts454-469
模块在应用程序引导过程中注册。 DependenciesScanner 负责扫描模块及其依赖项。
来源: packages/core/scanner.ts75-111
模块扫描过程涉及
来源: packages/core/scanner.ts106-174
功能模块是标准模块,按特定功能区域组织应用程序代码。它们包含与应用程序特定功能相关的提供者和控制器。
全局模块无需导入即可在应用程序的所有其他模块中使用。这是通过在模块上设置 isGlobal 标志来实现的。
容器使用此标志将全局模块绑定到所有其他模块。
来源: packages/core/injector/module.ts95-101 packages/core/scanner.ts103
动态模块是可以在导入时进行自定义的模块。它们是使用返回 DynamicModule 对象的工厂方法创建的。
在扫描模块时,动态模块的处理方式不同。
来源: packages/core/scanner.ts716-720 packages/core/scanner.ts131-144
模块系统的关键方面之一是如何解析模块之间的依赖关系。当一个模块导入另一个模块时,它可以访问该模块导出的提供者。
当一个模块导入另一个模块时,DependenciesScanner 会将导入的模块添加到导入模块的 imports 集合中。
来源: packages/core/scanner.ts418-426
Injector 负责解析提供者之间的依赖关系。当实例化提供者时,其依赖项会通过模块图进行解析。
来源: packages/core/injector/injector.ts109-186 packages/core/injector/injector.ts447-475
Module 类会验证导出的提供者要么由模块本身提供,要么从其他模块导入。
来源: packages/core/injector/module.ts485-501
NestJS 中的模块构成了一个图结构。为了优化依赖解析,NestJS 使用拓扑树计算每个模块与根模块的“距离”。
此距离计算有助于优化依赖解析过程。
来源: packages/core/scanner.ts397-416 packages/core/injector/topology-tree/topology-tree.ts1-57
在应用程序引导过程中,InstanceLoader 负责初始化每个模块中的所有提供者和控制器。这发生在所有模块都已注册并扫描其依赖项之后。
前向引用允许模块之间存在循环依赖。 forwardRef() 函数返回一个特殊对象,模块系统可以处理该对象。
来源: packages/core/scanner.ts421-423
每个模块都可以访问 ModuleRef,它可用于从模块中检索提供者。
这允许在运行时动态访问提供者。
来源: packages/core/injector/module.ts597-647
NestJS 支持各种类型的自定义提供者:
来源: packages/core/injector/module.ts305-324
NestContainer 作为应用程序中所有模块的注册表。它提供添加、替换和检索模块的方法。
来源: packages/core/injector/container.ts31-693
NestJS 模块系统为组织应用程序代码和管理依赖关系提供了一个强大的基础。通过将相关代码封装在模块中,并在应用程序的不同部分之间建立清晰的界限,它提高了可维护性和可伸缩性。主要功能包括:
@Module() 装饰器进行结构化组织理解模块系统对于构建结构良好的 NestJS 应用程序至关重要。