第2章 Nest.js入门

小编007 2026-01-01 03:16 16 0
2026-01-01 03:16
第1楼

摘要:js,那么第一步是先通过官方文档安装NestJS 命令行工具(CLI),安装后可以在系统的任何目录下使用nest 命令。通过win+R组合快捷键呼出运行窗口,输入cmd进入终端,复制以下命令回车执行。 Vue.2.2 src文件夹内容介绍 src文件夹下的app.controller.


学习Nest.js可以通过官方文档:Documentation | NestJS - A progressive Node.js framework。Nest官方文档如图2-1所示。

image-20251211155326802

图2-1 Nest.js官方文档

英文掌握薄弱可采用全文翻译为中文或者在浏览器扩展中下载插件“沉浸式翻译 - 网页翻译插件 | PDF翻译 | 免费",配置后,可通过快捷键进行中英文对照翻译,更适合阅读理解,如图2-2所示。

image-20251211224527050

图2-2 Nest.js官方文档-局部翻译

如果没有学习过Nest.js,第一个疑惑是它是干什么的?Nest.js是提供HTTP服务的框架。并且Nest.js是基于Express实现(即Nest.js底层是默认基于Express封装,也可以选择Fastify),并没有采用原生实现。

Express和Fastify要如何抉择?Express适合做业务层,而Fastify适合做网关层,根据自己实际情况决定。

2.1 安装Nest.js

假如你从未使用过Nest.js,那么第一步是先通过官方文档安装NestJS 命令行工具(CLI),安装后可以在系统的任何目录下使用nest 命令。通过win+R组合快捷键呼出运行窗口,输入cmd进入终端,复制以下命令回车执行。

Vue.js 2的主流时期也是采用CLI的方式构建项目,后续逐渐迁移到Vite中,而NestJS的CLI使用方式和过往的CLI都是一致的。

//全局安装 NestJS 命令行工具(CLI)
npm i -g @nestjs/cli

安装结束之后,通过nest --version命令检测NestJS 命令行工具是否安装成功,如图2-3所示。

image-20251211160755034

图2-3 Nest.js命令行工具安装

第二步就可以构建一个Nest.js项目,通过在终端输入以下命令构建项目。

// nest new <项目名>
nest new app

会生成如下问题:Which package manager would you ❤️ to use?(您将使用哪个包管理器),有npm、yarn和pnpm可选,推荐pnpm。项目构建成功如图2-4所示。

image-20251211161804681

图2-4 Nest.js构建项目

Nest.js构建的项目结构目录如图2-5所示。

image-20251211162120635

图2-5 Nest.js项目结构目录

从上往下解释分为四部分:

(1)node_modules文件夹:各种项目依赖包,在构建项目时就装好了,无需再次安装。

(2)src文件夹:源代码存放处。

(3)test文件夹:端到端(E2E)测试目录,这个不管。

(4)各类配置文件。

src文件夹下有四个ts文件,作用如下:

├── main.ts                    // 应用入口文件
├── app.module.ts              // 根模块(AppModule)
├── app.controller.ts          // 根控制器
├── app.service.ts             // 根服务
└── app.controller.spec.ts     // 控制器单元测试

配置文件总结如表1-1所示。

表1-1 Nest.js项目结构-配置文件

文件名类型主要作用关联工具/框架
package.json项目配置定义项目依赖、脚本命令、基本信息Node.js / npm
package-lock.json依赖锁锁定依赖版本,确保一致性npm
.gitignore忽略规则指定哪些文件/目录不应提交到 GitGit
.prettierrc代码格式化配置代码格式化规则(Prettier)Prettier
eslint.config.mjs代码检查配置 ESLint 代码质量检查规则ESLint
nest-cli.jsonCLI 配置NestJS 命令行工具的配置文件NestJS CLI
tsconfig.jsonTS 配置TypeScript 编译器配置(开发环境)TypeScript
tsconfig.build.jsonTS 构建配置TypeScript 生产构建配置TypeScript / NestJS
jest-e2e.json测试配置端到端(E2E)测试的 Jest 配置Jest
README.md文档项目说明文档-

以上是初始化项目的基础介绍。

2.2 src文件夹内容介绍

src文件夹下的app.controller.spec.ts单元测试文件在开发中是基本不会用到的,因此删除该文件。每次打包构建的时候都会重新创建该单元测试文件,因此我们在nest-cli.json配置文件中添加generateOptions配置项,将spec置为false,做完以上操作,构建项目就不会重新创建app.controller.spec.ts文件了。

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true
  },
  "generateOptions": {
    "spec": false
  }
}

此时src文件夹下4个文件的关联性就很强,文件功能如下4点:

(1)app.controller.ts:控制层,类似前端的路由。

(2)app.module.ts:协调app.controller.ts和app.service.ts文件,我们可以将app.module.ts文件理解为依赖注入的容器,通过@Module()装饰器实现模块整合。

//app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

(3)app.service.ts:具体业务实现。

以上3个文件夹分层和MVC架构具备一定的相似性,只不过没有view(视图层)。

(4) main.ts:应用启动入口,创建应用并实现应用的端口监听。

项目启动命令从package.json中的scripts配置项中查看,使用npm run start或者npm run start:dev都可以。启动项目之后到main.ts文件中查看具体端口(默认是3000端口),然后到浏览器中输入http://localhost:3000/进行访问。

Nest.js项目启动后展现的内容是来自app.service.ts文件的具体业务内容,如图2-6所示。

image-20251211164534329

图2-6 Nest.js项目启动-初始化效果

2.3 Nest命令

在终端输入Nest g --help就可以将所有的nest命令弹出,其中有些nest命令可用于创建nest元素,即nest文件,该部分命令总结如表1-2所示。

表1-2 Nest.js命令行部分命令

名称 (Name)别名 (Alias)描述 (Description)
applicationapplication生成一个新的应用工作空间
classcl生成一个新的类
configurationconfig生成 CLI 配置文件
controllerco生成控制器声明
decoratord生成自定义装饰器
filterf生成过滤器声明
gatewayga生成网关声明(WebSocket)
guardgu生成守卫声明
interceptoritc生成拦截器声明
interfaceitf生成接口
librarylib在 monorepo 中生成新的库
middlewaremi生成中间件声明
modulemo生成模块声明
pipepi生成管道声明
providerpr生成提供者声明
resolverr生成 GraphQL 解析器声明
resourceres生成新的 CRUD 资源
services生成服务声明
sub-appapp在 monorepo 中生成新的子应用

如果我们想在src文件夹下创建一个xiaoyu模块,我们需要找到src文件夹,创建xiaoyu文件夹,在xiaoyu文件夹下创建xiaoyu.module.ts文件,并且在app.module.ts中将XiaoyuModule注册到模块中。注意:我们可以在@Module()装饰器的imports配置项中导入其他模块。

// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { XiaoyuModule } from './xiaoyu/xiaoyu.module';

@Module({
  imports: [XiaoyuModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

但如果通过命令,只需要在终端通过nest g mo xiaoyu就能自动化的完成以上操作,包括自动在app.module.ts文件中注册模块。在终端中体现为新增xiaoyu.module.ts文件,改变app.module.ts文件,如图2-7所示。这可以减少我们一定的心智负担。

image-20251211165629149

图2-7 nest g mo xiaoyu命令效果

除了注册模块,还可以创建service服务层,命令为:nest g s xiaoyu;创建controller控制层,命令为:nest g co xiaoyu。如图2-8所示。xiaoyu.controller.ts和xiaoyu.service.ts文件通过命令生成后,会自动关联到xiaoyu.module.ts文件中,无需开发者额外补充操作。

image-20251211213027460

图2-8 nest g s/co xiaoyu命令效果

我们可以看到这些命令都在一定程度上体现对应的功能,例如刚才三点,因此通过理解关联就很容易记住。

(1)nest g mo <模块名称>=> module(模块)。

(2)nest g s <服务名称>=> service(服务)。

(3)nest g co <控制器名称>=> controller(控制)。

但常用的命令操作主要为:nest g res <模块名称>。表1-2的解释是生成增删改查的资源,听起来并不好理解,实际是生成一份完整结构的增删改查模块--Demo级别。

当我们在终端输入该命令:nest g res user,会弹出一段话What transport layer do you use?(你要使用哪种传输层协议?),然后给出如下5种选择:

(1)REST API。通过传统的 HTTP 路由方式提供接口,是最常用、最直观的 Web 接口风格。

(2)GraphQL(code first)。通过代码定义 GraphQL 架构,让类型和解析逻辑都由代码自动生成。(不好用)

(3)GraphQL(schema first)。先写 .graphql Schema,再根据 Schema 编写解析逻辑,更适合规范化协作。(不好用)

(4)Microservice(non-HTTP)。微服务,通过消息队列、TCP、gRPC 等方式实现服务间通信。

(5)WebSockets。用于创建实时、双向通信的长连接服务,如聊天室或实时推送。

我们选择第一种REST API就可以了。

此时会弹出第二个问题:Would you like to generate CRUD entry points?(你想生成增删改查的模板吗?),选Y(Yes),然后就会开始生成资源。

nest g res user命令效果如图2-9所示。

image-20251211214834047

图2-9 nest g res user命令效果

可以看到该命令一下就创建出controller、module、service三层文件(自动化配置),这些文件内部都会自动初始化一份基础的代码。其文件作用与2.2小节所介绍的src文件夹下的三个同类型文件的作用是一致的。因此展现的内容在user.service.ts文件中,而路由在user.controller.ts文件中。我们打开user.controller.ts文件可以看到默认的get和post方法以及一些参数方法。

如果想要测试Patch,Delete等请求,需要在VSCode中下载rest client,然后在test测试文件夹下创建index.http文件用于发送各种不同的请求来测试API接口。

// user.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {} // 来自业务层的展示内容

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.userService.findAll(); // 触发默认get请求后,返回业务层中的findAll方法下的展示内容。
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.userService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.userService.remove(+id);
  }
}

因此,只需要在原有URL的后缀添加/user就能访问到user模块下的默认get请求,而get请求的是user.service.ts业务层的内容,/user路由访问效果如图2-10所示。到这里,我们就理解控制层和业务层之间的联系合作(同时在模块层导入注册),并且完成了一次基础的模块创建并展示使用。

image-20251211223437609

图2-10 /user路由的访问效果

除此之外还有dto和entities两个文件夹,两个文件夹作用如下所示:

(1)dto文件夹:数据验证层。主要功能有:定义 API 请求、数据验证(使用 class-validator)、数据转换(使用 class-transformer)等等。内部有create-user.dto.ts和update-user.dto.ts文件,分别用来创建和更新用户的DTO。例如数据验证的做法如下代码所示。

// create-user.dto.ts
import {IsNotEmpty,IsString} from 'class-validator'
export class CreateUserDto {
    @IsNotEmpty() // 验证-不能为空
    @IsString() // 验证-需要是一个字符串
    account: string; // 账号
    @IsNotEmpty()
    @IsString()
    password: string; // 密码
}

(2)entities文件夹:实体层。定义数据库的,即映射数据库表结构(ORM 概念),但我们数据库使用Prisma7,所以不在entities文件夹定义,这里用不上了。

所以nest g res <模块名称>做到了nest g mo/s/co <模块名称>的合并效果并且还有额外的数据验证层和实体层,因此nest g res相对于连续写3个命令来创建对应模块结构会更为简便,在日常使用会更加高频。

  • 1 / 1 页
敬请注意:文中内容观点和各种评论不代表本网立场!若有违规侵权,请联系我们.