《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项目实战 等相关文章,敬请期待~~~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java的集合框架总结

Map接口和Collection接口是所有集合框架的父接口&#xff1a; Collection接口的子接口包括&#xff1a;Set接口和List接口 Map接口的实现类主要有&#xff1a;HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等 Set接口的实现类主要有&#xff1a;HashSet、Tr…

大数据实训项目(小麦种子)-03、大数据环境Hadoop、Mapreduce、Hive、Hbase、HDFS搭建服务及调试

文章目录 前言一、Linux系统Centos7安装配置JDK8二、Linxu系统Centos7中搭建Hadoop3.1.0服务下载地址服务1&#xff1a;详细步骤&#xff08;初始化与启动dfs服务&#xff09;详细步骤配置环境变量 服务2&#xff1a;Hadoop(YARN)环境搭建 三、Linux系统搭建Hive3.1.2服务前提条…

记录AE快捷键(持续补充中。。。)

记录AE快捷键 快捷键常用快捷键图层快捷键工具栏图层与属性常用指令视图菜单时间轴常规快捷键项目首选项功能摄像机操作 常用操作导入AI/PS工程文件加选一个关键参数快速回到上下一帧隐藏/显示图层关键帧拉长缩短关键帧按着鼠标左键不松手&#xff0c;在秒表那一列往下移动会都…

深度学习(PyTorch)批注理解,建议边学可以边看这个笔记

前言 动手学习深度学习&#xff0c;内容丰富&#xff0c;但是对于初学者有很多晦涩难懂的地方&#xff0c;我将日常更新这篇文章以截图的形式&#xff0c;每天高强度学习四五个小时&#xff0c;精力缺乏&#xff0c;我认为&#xff0c;如果想学习这个深度学习&#xff0c;你需…

ubuntu vnc

如何在Ubuntu 18.04安装VNC | myfreax sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt install tigervnc-standalone-server tigervnc-common vncserver sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt ins…

5.数据仓库与数据挖掘期末复习

ETL的含义Extract 、 Transformation、Load。ODS的全称Operational Data Store。 DW全称 Data WarehourseDM全称是Data Mart数据仓库数据抽取时所用到技术是增量、全量、定时、调度STAGE层作用是提供业务系统数据文件的临时存储ODS层作用ods提供业务系统细节数据长期沉淀MID层…

实用软件下载:BetterZip 5最新安装包及详细安装教程

BetterZip是一款功能强大的Mac解/压缩软件&#xff0c;可以满足用户对文件压缩、解压、加密和保护等方面的需求。以下是关于BetterZip软件的主要功能、特点和使用方法的详细介绍&#xff0c;以及对其用户友好度、稳定性和安全性的评价。 安 装 包 获 取 地 址: BetterZip 5-安…

057、PyCharm 运行代码报错:Error Please select a valid Python interpreter

当我们在PyCharm运行代码时&#xff0c;提示如下图错误&#xff1a; 那么问题通常是由于PyCharm未正确配置Python解释器引起的。 我们只需按以下步骤重新配置Python解释器即可&#xff1a; 打开PyCharm设置&#xff1a; 在菜单栏中的点击 “File” -> “Settings”&#xf…

选择性语言建模:下一代语言模型训练方法

在人工智能领域&#xff0c;语言模型的预训练方法一直是研究的热点。传统的语言模型预训练方法普遍采用一种均匀的策略&#xff0c;即对所有训练数据中的下一个词进行预测&#xff0c;这种方法被称为因果语言建模&#xff08;Causal Language Modeling, CLM&#xff09;。虽然C…

Nginx配置详细解释:(6)实现反向代理服务器,动静分离,负载均衡

目录 单台反向代理 proxy_pass后面加不加/的问题&#xff1a; 反向代理动静分离 反向代理负载均衡 作为代理服务器是当客户端访问代理服务器时&#xff0c;代理服务器代理客户端去访问真实web服务器。proxy_pass; 用来设置将客户端请求转发给的后端服务器的主机。 需要模块…

Android入门第69天-AndroidStudio中的Gradle使用国内镜像最强教程

背景 AndroidStudio默认连接的是dl.google的gadle仓库。 每次重新build时: 下载速度慢;等待了半天总时build faild;build到一半connection timeout;即使使用了魔法也难以一次build好;这严重影响了我们的学习、开发效率。 当前网络上的使用国内镜像的教程不全 网上的教程…

C++100行超简单系统

非常好用&#xff0c;小白也可以自己修改 先来看图片&#xff1a; 用法附在代码里了&#xff01; #include <bits/stdc.h> #include <windows.h>using namespace std;struct users {string name;string num; bool f; } u[10000];int now_users 0; /*当前用户数*…

20240615在WIN11下的串口调试助手的下载安装以及使用

20240615在WIN11下的串口调试助手的下载安装以及使用 2024/6/15 18:06 百度&#xff1a;串口调试助手 blob:https://apps.microsoft.com/df934d29-fd7a-4873-bb6b-a4ab5a7934c9 串口调试助手 Installer.exe 收发的LOG&#xff1a; rootok3588:/# ./uart_test /dev/ttyS0 11520…

C++ bfS

岛屿的最大面积 . - 力扣&#xff08;LeetCode&#xff09; 1.刚开始mn又加了int 2.bfs里符合条件了&#xff0c;不push&#xff0c;&#xff0c;&#xff0c;在写什么几把 class Solution { public:int dx[4] {0, 0, 1, -1};int dy[4] {1, -1, 0, 0};bool vis[50][50];int…

【博士每天一篇文献-算法】Progressive Neural Networks

阅读时间&#xff1a;2023-12-12 1 介绍 年份&#xff1a;2016 作者&#xff1a;Andrei A. Rusu,Neil Rabinowitz,Guillaume Desjardins,DeepMind 研究科学家,也都是EWC(Overcoming catastrophic forgetting in neural networks)算法的共同作者。 期刊&#xff1a; 未录用&am…

调教LLaMA类模型没那么难,LoRA将模型微调缩减到几小时

简介&#xff1a; 调教LLaMA类模型没那么难&#xff0c;LoRA将模型微调缩减到几小时 LoRA 微调方法&#xff0c;随着大模型的出现而走红。 最近几个月&#xff0c;ChatGPT 等一系列大语言模型&#xff08;LLM&#xff09;相继出现&#xff0c;随之而来的是算力紧缺日益严重。虽…

python如何对list求和

如何在Python中对多个list的对应元素求和&#xff0c;前提是每个list的长度一样。比如&#xff1a;a[1&#xff0c;2&#xff0c;3]&#xff0c;b[2&#xff0c;3&#xff0c;4]&#xff0c;c[3&#xff0c;4&#xff0c;5]&#xff0c;对a&#xff0c;b&#xff0c;c的对应元素…

分数计算 初级题目

今天继续更题。今天的题目是《第五单元 分数的加减法》初级题目。 定位&#xff1a;题目较为初级&#xff0c;适合预习 参考答案&#xff1a;CACCADACAABACBBCDBCB

Linux文件系统【真的很详细】

目录 一.认识磁盘 1.1磁盘的物理结构 1.2磁盘的存储结构 1.3磁盘的逻辑存储结构 二.理解文件系统 2.1如何管理磁盘 2.2如何在磁盘中找到文件 2.3关于文件名 哈喽&#xff0c;大家好。今天我们学习文件系统&#xff0c;我们之前在Linux基础IO中研究的是进程和被打开文件…

【DevOps】 什么是容器 - 一种全新的软件部署方式

目录 引言 一、什么是容器 二、容器的工作原理 三、容器的主要特性 四、容器技术带来的变革 五、容器技术的主要应用场景 六、容器技术的主要挑战 七、容器技术的发展趋势 引言 在过去的几十年里,软件行业经历了飞速的发展。从最初的大型机时代,到后来的个人电脑时代,…