nestjs 全栈进阶--module

视频教程

10_模块@Module1_哔哩哔哩_bilibili

1. 模块@Module

在 Nest.js 中,Module 是框架的核心概念之一,用于组织和管理应用程序的不同部分,包括服务、控制器、中间件以及其他模块的导入。每个 Nest.js 应用程序至少有一个根模块(通常命名为 AppModule),并且可以根据需要创建更多的模块以实现更好的代码组织和模块化。

模块的主要功能和用途包括:

  1. 服务注册
    • 使用 providers 属性来注册服务,这些服务可以被其他模块通过依赖注入(DI)系统来获取和使用。
  1. 控制器注册
    • 使用 controllers 属性来注册控制器,它们处理 HTTP 请求并返回响应。
  1. 模块导入
    • 使用 imports 属性来导入其他模块,这样就可以在整个应用范围内共享和使用已导入模块的控制器和服务。
  1. 导出提供者
    • 使用 exports 属性来导出模块内的服务和其他提供者,使其可供其他导入该模块的模块使用。
  1. 全局中间件
    • 使用 middleware 属性注册全局中间件,这些中间件会对所有的 HTTP 请求生效。
  1. 路由前缀
    • 通过 path 属性为模块内的所有控制器添加路由前缀,方便进行路由分组和管理。
  1. 配置绑定
    • 可以在模块级别绑定配置对象,这些配置可在模块内的服务中通过 @Inject() 注解注入和使用。
  1. 动态模块
    • 通过 register() 或forRoot() 或 forFeature() 方法,可以创建动态模块,根据需要动态加载和配置模块。
nest new module -p pnpm
pnpm start:dev

2. 基本用法

nest g res aaa

当我们使用nest g res aaa 创建一个CURD 模板的时候 nestjs 会自动帮我们引入模块

在aaa.module中也自动处理了AaaController, AaaService

3. 共享模块

nest g resource bbb --no-spec // --no-spec 是不生成测试文件

在 AaaModule 里指定 exports 的 provider:

然后在 BbbModule 里 imports:

这样就可以在bbb中使用aaa的service了

pnpm run start:dev
http://localhost:3000/bbb

4. 全局模块

如果这个 AaaModule 被很多地方引用,每个模块都 imports 太麻烦了,这时候就可以把它声明为全局的

@Global()

我们给 aaa 模块添加 @Global() 他便注册为全局模块

在bbb 模块使用无须在module import 导入

依然是可以注入的:

注:全局模块尽量少用,注入的很多 provider 不知道来源,降低代码的可维护性。

5. 动态模块

我们上面讲的模块都是静态的,也就是它的内容是固定不变的,每次 import 都是一样,有的时候我们希望 import 的时候给这个模块传一些参数,动态生成模块的内容,这时就需要用到动态模块了。

动态模块主要就是为了给模块传递参数 可以给该模块添加一个静态方法 用来接受参数

nest g resource ccc --no-spec // --no-spec 是不生成测试文件

他自动生成的模块是这样的

我们现在来改成Dynamic Module

我们给 CccModule 加一个 register 的静态方法,返回模块定义的对象。和在装饰器里定义的时候的区别,只是多了一个 module 属性。

现在我们在去app.module中重新处理下他的import

import 的时候就得这样用了,通过 register 方法传入参数,返回值就是模块定义,现在我们在运行项目,访问http://localhost:3000/ccc

可以看到依然是正常的

而且这时候我们把传入的 options 通过 useValue 创建的 provider,这样模块内部就可以注入它了。

再次在浏览器访问

这样我们就可以在 import 一个模块的时候,传入参数,然后动态生成模块的内容,这就是 Dynamic Module。

register 这个方法其实叫啥都行,但 nest 约定了 3 种方法名:

  • register:用一次模块传一次配置,比如这次调用是 CccModule.register({name: 'xt'}),下一次就是 CccModule.register({name: 'lxc'}) 了
  • forRoot:配置一次模块用多次,比如 XxxModule.forRoot({}) 一次,之后就一直用这个 Module,一般在 AppModule 里 import
  • forFeature:用了 forRoot 固定了整体模块,用于局部的时候,可能需要再传一些配置,比如用 forRoot 指定了数据库链接信息,再用 forFeature 指定某个模块访问哪个数据库和表。

其实 forRoot、forFeature、register 本质上没区别,只是我们约定了它们使用上的一些区别。

6. Nest 提供创建动态模块的方式

nest g module ddd
nest g controller ddd --no-spec

这次我们不手动写 register、registerAsync 等方法了,用 builder 来生成。

import { ConfigurableModuleBuilder } from "@nestjs/common";

export interface DddModuleOptions {
  name: string;
  age: number;
}

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<DddModuleOptions>().build();

用 ConfigurableModuleBuilder 生成一个 class,这个 class 里就带了 register、registerAsync 方法。

返回的 ConfigurableModuleClass、MODULE_OPTIONS_TOKEN 分别是生成的 class 、options 对象的 token。

然后 DddModule 继承它,这样这个 DddModule 就已经有了 register 和 registerAsync 方法了

那现在如何在 Module 内注入这个 options 呢?记得 build class 的时候返回了一个 token 么?

就用这个注入:

当然,options 对象不是这么用的,一般是用来做配置,内部的 provider 基于它来做一些设置,这里只是演示。

你还可以用 registerAsync 方法,用 useFactory 动态创建 options 对象:

前面我们说还可以用 forRoot、forFeature 这样的方法,那用 builder 的方式如何生成这样的 class 呢?调用 setClassMethodName 设置下就好了

如果你还想根据传入的参数决定是否设置为全局模块,那就要这样写

import { ConfigurableModuleBuilder } from "@nestjs/common";

export interface DddModuleOptions {
  name: string;
  age: number;
}

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<DddModuleOptions>().setClassMethodName('register').setExtras({
    isGlobal: true,
  }, (definition, extras) => ({
    ...definition,
    global: extras.isGlobal,
  })).build();

setExtras 第一个参数是给 options 扩展啥 extras 属性,第二个参数是收到 extras 属性之后如何修改模块定义。我们定义了 isGlobal 的 option,收到它之后给模块定义加上个 global。

然后我们会发现一个问题, 在我们使用的时候他没有isGlobal 属性

因为我们用的是这个类型:

我们应该用builder 返回的类型

这个 ASYNC_OPTIONS_TYPE 是 async 方式创建模块的 otpion 类型.

在实际项目中 你可以自己创建动态模块,也可以使用nest提供的 ConfigurableModuleBuilder,它只是对我们定义 register、registerAsync 的过程做了封装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/524484.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【QT+QGIS跨平台编译】076:【libdxfrw跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、libdxfrw介绍二、QGIS下载三、文件分析四、pro文件五、编译实践一、libdxfrw介绍 libdxfrw是一个用于读取和写入DXF(Drawing Exchange Format)文件的开源C++库。DXF是一种由AutoCAD开发的文件格式,用于存储CAD(计算机辅助设计)图形数据,它…

【代码随想录】哈希表

文章目录 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和454. 四数相加 II383. 赎金信15. 三数之和18. 四数之和 242.有效的字母异位词 class Solution {public boolean isAnagram(String s, String t) {if(snull || tnull || s.length()!t.length()){return …

基于计算机视觉的交通信号违章检测系统(闯红灯违章检测)

Introduce: 该系统可以实时检测交通信号灯违规: 城市中越来越多的汽车会导致大量交通拥堵&#xff0c;这意味着如今在孟加拉国和世界各地&#xff0c;交通违规行为变得更加严重。这造成了严重的财产破坏和更多可能危及人民生命的事故。为了解决令人震惊的问题并防止这种深不可…

Flask Python Flask-SQLAlchemy中数据库的数据类型、flask中数据可的列约束配置

Flask Python Flask-SQLAlchemy中数据库的数据类型、flask中数据可的列约束配置 SQLAlchemy官方文档地址实战的代码分享数据类型列约束配置自定义方法 SQLAlchemy官方文档地址 SQLAlchemy官方文档地址 实战的代码分享 Flask-SQLAlchemy框架为创建数据库的实例提供了一个基类…

Stirling PDF:免费PDF开源编辑工具

Git地址&#xff1a;https://github.com/Stirling-Tools/Stirling-PDF Stirling-PDF是一个基于spring-boot开发的开源项目&#xff0c;旨在提供一个功能强大的基于Docker的本地托管PDF操作工具。它使您能够对PDF文件进行多种操作&#xff0c;包括拆分、合并、转换、重新组织、…

git系列之--- git pull 和 git fetch理解与区别

标题一般远端仓库里有新的内容更新&#xff0c;当我们需要把新内容下载的时候&#xff0c;就使用到git pull或者git fetch命令 fetch 用法如下&#xff1a; git fetch <远程主机名> <远程分支名>:<本地分支名>例如从远程的origin仓库的master分支下载代码…

如何在 iPhone 15/14/13/12/11/XS/XR 上恢复误删除的短信?

无论你的iPhone功能多么强大&#xff0c;数据丢失的情况仍然时有发生&#xff0c;所以当你发现一些重要的消息有一天丢失了。别担心&#xff0c;让自己冷静下来&#xff0c;然后按照本页的方法轻松从 iPhone 中检索已删除的短信。 在这里&#xff0c;您需要奇客数据恢复iPhone…

2024-4-7 QT day1作业

myWidget.cpp #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//设置窗口标题this->setWindowTitle("QQ");//设置窗口图标this->setWindowIcon(QIcon("C:\\Users\\张谦\\Desktop\\pictrue\\qq.png"));//设…

网络——初识网络

在现如今&#xff0c;网络已经成了一种基础设施&#xff0c;大到国家&#xff0c;小到个人&#xff0c;网络已经充斥在我们每个人的身 边&#xff0c;如果一个人突然失去了网络&#xff0c;那么它的生活或多或少会出现一些不方便的地方&#xff0c;网络现在已 经伴随着我们的吃…

【Python-数据类型】

Python-数据类型 ■ 类型简介■ Number&#xff08;数字&#xff09;■ String&#xff08;字符串&#xff09;■ Python 转义字符■ Python 字符串运算符■ Python 字符串格式化■ Python三引号■ f-string ■ bool&#xff08;布尔类型&#xff09;■ List&#xff08;列表&a…

OSPF实例是什么?

OSPF实例是什么&#xff1f; **OSPF实例指的是一个OSPF路由进程&#xff0c;它是在一个设备上运行的单独的OSPF路由协议实体**。 在详细解释这个概念之前&#xff0c;需要了解OSPF&#xff08;Open Shortest Path First&#xff09;是一种内部网关协议&#xff08;IGP&#x…

【pycharm报错】rror: Microsoft Visual C++ 14.0 or greater is required.

一、报错 二、下载vs 路径&#xff1a;https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/ 三、安装 四、安装成功并启动 重新安装chromadb成功

如何在 Node.js 中使用 bcrypt 对密码进行哈希处理

在网页开发领域中&#xff0c;安全性至关重要&#xff0c;特别是涉及到用户凭据如密码时。在网页开发中至关重要的一个安全程序是密码哈希处理。 密码哈希处理确保明文密码在数据库受到攻击时也难以被攻击者找到。但并非所有的哈希方法都是一样的&#xff0c;这就是 bcrypt 突…

实战webSocket压测(三)Jmeter真实接口联调

背景&#xff1a; 接口地址为&#xff1a;ws://sunlei.demo 接口说明&#xff1a;websocket接口&#xff0c;首次连接&#xff0c;通过Text请求设置开启标志&#xff0c;然后通过wav文件流传输&#xff0c;达到后端服务可以根据传输信息进行解析满足指定标准后&#xff0c;web…

【Linux】有关时间的命令(date、timedatectl)

专栏文章索引&#xff1a;Linux 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、data命令 1.介绍 2.常用参数 3.常用选项 二、timedatectl命令 1.介绍 2.常用子命令 一、data命令 1.介绍 date命令用于显示或设置系统的时间与日期&#xff0c;语法格式为&a…

前端:SVG绘制流程图

效果 代码 html代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>SVG流程图示例</title><style>/* CSS 样式 */</style><script src"js/index.js"></script…

设计模式浅析(十) ·设计模式之迭代器组合模式

设计模式浅析(十) 设计模式之迭代器&组合模式 日常叨逼叨 java设计模式浅析&#xff0c;如果觉得对你有帮助&#xff0c;记得一键三连&#xff0c;谢谢各位观众老爷&#x1f601;&#x1f601; 案例 有两家门店&#xff0c;门店A呢只提供早餐&#xff0c;门店B呢只提供午…

IntelliJ IDEA 2024.1 更新亮点汇总:全面提升开发体验

IntelliJ IDEA 2024.1 更新亮点汇总&#xff1a;全面提升开发体验 文章目录 IntelliJ IDEA 2024.1 更新亮点汇总&#xff1a;全面提升开发体验摘要引言 IntelliJ IDEA 2024.1 的新增功能主要亮点全行代码完成 最终的支持 Java 22 功能新航站楼 贝塔编辑器中的粘滞线 人工智能助…

2024新版PHP在线客服系统多商户AI智能在线客服系统源码机器人自动回复即时通讯聊天系统源码PC+H5

搭建环境&#xff1a; 服务器 CPU 2核心 ↑ 运存 2G ↑ 宽带 5M ↑ 服务器操作系统 Linux Centos7.6-7.9 ↑ 运行环境&#xff1a; 宝塔面板 Nginx1.18- 1.22 PHP 7.1-7.3 MYSQL 5.6 -5.7 朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持…

深入浅出 -- 系统架构之负载均衡Nginx实现高可用

一、Nginx的高可用 线上如果采用单个节点的方式部署Nginx&#xff0c;难免会出现天灾人祸&#xff0c;比如系统异常、程序宕机、服务器断电、机房爆炸、地球毁灭....哈哈哈&#xff0c;夸张了。但实际生产环境中确实存在隐患问题&#xff0c;由于Nginx作为整个系统的网关层接入…