《Nest系列 - 1. 运行一个Nest项目以及整体目录学习》

2024-06-14 17:04

本文主要是介绍《Nest系列 - 1. 运行一个Nest项目以及整体目录学习》,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

初识Nest心路历程

作为一名前端开发,说实话,学习Nest后端技术, 会有一定的成本。我试着阅读文档,安装项目,把项目跑起来,

当我看到久违的Hellow world 后,还来不及欣喜,就困惑了, 作为一个后端框架,数据不是都会在浏览器 NetWork里看返回的数据,这怎么还直接显示在页面了

image.png

image.png

这让我对 MVC的理解,又有点模糊了 。

当我正要查看代码,发现和vue项目的整体结构还差不多,但是当我打开具体的目录,又懵逼了,@Controller(), @Get(), @Module 这都什么玩意,当我再起看文档

依赖注入,控制反转,装饰器,中间件,管道 看到这些名词,就已经把我劝退了。

image.png

当我再看到 模块,中间件,异常过滤器,守卫,拦截器 又感觉还能学,这不就是模块,axios请求,拦截,路由守卫那一部分的知识。

终于当我历经几天的犹豫,决定入坑Nest后端框架,下面就让我们开始学习Nest系列文章

项目脚手架 安装

使用脚手架Nest CLI 构建项目

// 安装全局@nestjs/cli
1. npm i -g @nestjs/cli// 创建一个nest项目
2. nest new project-name// 运行项目
3. pnpm run start:dev

选择一个包管理工具,静待安装完毕

image.png

运行项目

image.png

image.png

项目目录说明

+-- dist[目录]                      // 编译后的目录,用于预览项目
+-- node_modules[目录]              // 项目使用的包目录,开发使用和上线使用的都在里边
+-- src[目录]                       // 源文件/代码,程序员主要编写的目录
|  +-- app.controller.spec.ts      // 对于基本控制器的单元测试样例
|  +-- app.controller.ts           // 控制器文件,可以简单理解为路由文件
|  +-- app.module.ts               // 模块文件,在NestJS世界里主要操作的就是模块
|  +-- app.service.ts              // 服务文件,提供的服务文件,业务逻辑编写在这里
|  +-- app.main.ts                 // 项目的入口文件,里边包括项目的主模块和监听端口号
+-- test[目录]                      // 测试文件目录,对项目测试时使用的目录,比如单元测试...
|  +-- app.e2e-spec.ts             // e2e测试,端对端测试文件,测试流程和功能使用
|  +-- jest-e2e.json               // jest测试文件,jset是一款简介的JavaScript测试框架
+-- .eslintrc.js                   // ESlint的配置文件
+-- .gitignore                     // git的配置文件,用于控制哪些文件不受Git管理
+-- .prettierrc                    // prettier配置文件,用于美化/格式化代码的
+-- nest-cli.json                  // 整个项目的配置文件,这个需要根据项目进行不同的配置
+-- package-lock.json              // 防止由于包不同,导致项目无法启动的配置文件,固定包版本
+-- package.json                   // 项目依赖包管理文件和Script文件,比如如何启动项目的命令
+-- README.md                      // 对项目的描述文件,markdown语法
+-- tsconfig.build.json            // TypeScript语法构建时的配置文件
+-- tsconfig.json                  // TypeScript的配置文件,控制TypeScript编译器的一些行为  

src目录下的文件说明

src目录是日常工作编写代码的主要目录,从基本的目录结构也可以对NestJS编写模式有很好的了解。

+-- src[目录]                       // 源文件/代码,程序员主要编写的目录
|  +-- app.controller.spec.ts      // 对于基本控制器的单元测试样例
|  +-- app.controller.ts           // 控制器文件,可以简单理解为路由文件
|  +-- app.module.ts               // 模块文件,在NestJS世界里主要操作的就是模块
|  +-- app.service.ts              // 服务文件,提供的服务文件,业务逻辑编写在这里
|  +-- app.main.ts                 // 项目的入口文件,里边包括项目的主模块和监听端口号

细节的东西不用关心太多,我们需要先把整个项目的架构,大体运行机制搞明白,才能进行下面细致入微的学习

1. 从app.main.ts 入口文件开始看起

image.png

  • 通过 @nestjs/core 导入 NestFactory

  • 主要作用是Use NestFactory to create an application instance 使用NestFactory创建应用程序实例

  • 然后使用实例设置监听端口

这就跟我们在 vue 中一样,创建一个实例

 import { createApp } from 'vue'import App from './App.vue'const app = createApp(App)

我们是把html 文件中的 <div id="app"></div>挂载到 实例上 app.mount(‘#app’)

而在Nest 中,是把AppModule(模块),挂载到实例上。

2. 那具体AppModule 是什么呢?

image.png

AppModule这个类 啥也没干,就导出了? export class AppModule {}

image.png

其实不然,这里遇到了第一个新的概念: 装饰器

@Module - 当类被 module 装饰器装饰的时候,它就是一个模块。从代码层面来看,这个模块的作用就是组合AppController 和 AppService ,把他们聚合在一起,供 AppModule 使用

  1. AppController 是什么呢?

image.png

这个实例并不明显,因为没有体现出他的路由作用,那要是我这样写,你或许就明白了

image.png

@Get('index') 就是请求方法类型, 参数是路径/参数
在里面调用了 appService.getHello 的方法 来返回具体的结果

从前端的角度来看Nest的执行顺序

我们请求一个接口 大致流程 是这样的 传递路径/参数 服务端返回对应的结果


axios.get('/user?ID=12345').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});

服务端,在 controller 层会对路由做一个匹配 匹配到响应的路由,service 去做业务逻辑/和数据库交互

疑问点答疑

1. 全篇都是export class ,怎么没见new 实例化调用呢?

在 NestJS 中,大部分组件(如控制器、服务、模块等)都是通过 class 来定义的,而且通常不需要显式地使用 new 关键字来实例化这些组件。这是因为 NestJS 基于依赖注入(Dependency Injection)的设计理念,在运行时由 NestJS 框架负责创建和管理组件的实例。

这也是我在学Nest最大的一个疑惑,也是Nest中比较伟大的一个设计,@Injectable,@Controller,下面跟了一个class ,就代表这个class 是可以被注入的,换句话说,就是这个class ,我Nest 会自动帮你进行 new 操作,你直接调用里面的方法举行

@Controller()
export class AppController {constructor(private readonly appService: AppService) {}@Get()getHello(): string {return this.appService.getHello(); // AppService 这个类,没有new,就可以直接使用实例上的方法,是因为她是可以被注入的,也就是有@Inject,Nest 会自动帮我们注入到AppController中}
}
依赖注入(Dependency Injection)

依赖注入是一种设计模式,通过它,类的依赖关系可以在运行时动态地注入到类中而不是在类内部直接创建依赖的实例。在 NestJS 中,组件之间的依赖关系通过依赖注入实现,这样可以更好地解耦组件之间的关系,提高代码的可测试性和可维护性。

举个例子,当你在一个 NestJS 控制器的构造函数中声明一个服务作为参数时,NestJS 框架会自动注入该服务的实例,而不需要手动创建。例如:

typescriptCopy Code
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';@Controller('users')
export class UserController {
// 注入的方式可以是构造器注入:constructor(private readonly appService: AppService) {}
// 或者属性注入:
// @Inject(AppService)
// private readonly appService: AppService@Get()findAll(): string {return this.appService.findAll();}
}

在上面的例子中,AppService 被声明为 UserController 的构造函数的参数,通过 TypeScript 的语法,private readonly appService: AppService 相当于声明了一个私有成员变量,并将传入的 AppService 实例赋给了这个成员变量。NestJS 框架在初始化 UserController 时,会自动创建并注入 AppService 的实例。

这种方式使得代码更加简洁,同时也减少了对全局状态的依赖,使得组件更容易被复用和测试。

因此,在 NestJS 中,通常不需要手动使用 new 关键字来实例化,框架会在需要的时候自动处理组件的创建和注入。

这个和前端模块很相似,模块有导出,就有导入,才能使用。而 在Nest中,模块导出,需要导入并且使用new 去实例化类,但是不是通过new 来实例化,而是通过依赖注入的方式去实例化,并且后续调用实例上的方法

总结

  1. 可以使用cli快速搭建项目,并且运行项目
  2. 对每个目录进行分析,掌握整体项目结构
  3. 从app.main.ts 出来,开始 逐步分析,通过NestFactory创建一个实例,然后把模块传入
  4. 模块就是一个集合,里面聚合了Controller,Service
  5. Controller 就是一个控制器文件,可以简单理解为路由文件,里面会设置请求方法/请求参数, 然后调用Service 类 来做业务逻辑处理/和数据库交互
  6. 这么多的class ,都不需要new 去实例化调用,而且调用关系/调用顺序怎么处理,最主要的是利用了依赖注入这个设计模式,类的依赖关系可以在运行时动态地注入到类中,而不是在类内部直接创建依赖的实例。
  7. 依赖注入可以是构造器注入,也可以是属性注入,相比构造器注入更简便,但是属性注入易读性更强
  8. 只要是类,只要被装饰器修饰,类的依赖关系可以在运行时动态地注入到类中,而不是在类内部直接创建依赖的实例

后记

后面会陆续完成装饰器/CURD/ 中间件/日志/api 文档/Nest项目实战 等相关文章,敬请期待~~~

这篇关于《Nest系列 - 1. 运行一个Nest项目以及整体目录学习》的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061001

相关文章

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

如何使用Maven创建web目录结构

《如何使用Maven创建web目录结构》:本文主要介绍如何使用Maven创建web目录结构的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录创建web工程第一步第二步第三步第四步第五步第六步第七步总结创建web工程第一步js通过Maven骨架创pytho

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关