介绍及安装
介绍及安装
介绍
1、Nestjs 是一个用于构建高效可扩展的一个基于Node js 服务端 应用程序开发框架,并且完全支持typeScript 结合了 AOP 面向切面的编程方式
2、nestjs 还是一个spring MVC 的风格 其中有依赖注入 IOC 控制反转 都是借鉴了Angualr
3、nestjs 的底层代码运用了 express 和 Fastify 在他们的基础上提供了一定程度的抽象,同时也将其 API 直接暴露给开发人员。这样可以轻松使用每个平台的无数第三方模块
内置框架express
默认express,能够快速构建服务端应用程序,且学习成本非常低,容易上手
内置框架 Fastify
- 高性能: 据我们所知,Fastify 是这一领域中最快的 web 框架之一,另外,取决于代码的复杂性,Fastify 最多可以处理每秒 3 万次的请求。
- 可扩展: Fastify 通过其提供的钩子(hook)、插件和装饰器(decorator)提供完整的可扩展性。
- 基于 Schema: 即使这不是强制性的,我们仍建议使用 JSON Schema 来做路由(route)验证及输出内容的序列化,Fastify 在内部将 schema 编译为高效的函数并执行。
- 日志: 日志是非常重要且代价高昂的。我们选择了最好的日志记录程序来尽量消除这一成本,这就是 Pino!
- 对开发人员友好: 框架的使用很友好,帮助开发人员处理日常工作,并且不牺牲性能和安全性。
- 支持 TypeScript: 我们努力维护一个 TypeScript 类型声明文件,以便支持不断成长的 TypeScript 社区。
安装
Nestjs 官方提供了一个很好用的脚手架工具,可以用来快速创建,开发和构建一个 Nestjs 应用。
nest 可以使用的命令
- nest new 快速创建项目
- nest generate 快速生成各种代码
- nest build 使用 tsc 或者 webpack 构建代码
- nest start 启动开发服务,支持 watch 和调试
- nest info 打印 node、npm、nest 包的依赖版本
在 package.json
中修改 dev
的命令,便于调试,可以实时监听代码修改
"dev": "nest start --watch",
快速开始
首先全局安装脚手架工具
npm install -g @nestjs/cli
查看脚手架版本号
nest -v
使用脚手架提供的 new 命令创建项目
nest new <项目名称>
命令行中会提示选择一个你想要的包管理工具,这里使用npm方式

稍等片刻,这是项目项目初始化完成后的样子

根据提示,进入项目目录,执行启动命令,即可运行一个 Nestjs 应用了
cd nest-demo
npm run start

在命令行窗口中,有一些打印的信息,我们可以简单看一下
> nest-demo@0.0.1 start
这一行是项目的名字以及版本号,和项目所在路径
> nest start
这一行是启动项目的命令
[Nest] 21804 - 2024/12/23 13:28:35 LOG [NestFactory] Starting Nest application...
NestFactory(Nest 工厂类)日志,启动了 Nest 应用
[Nest] 21804 - 2024/12/23 13:28:35 LOG [InstanceLoader] AppModule dependencies initialized +17ms
InstanceLoader(实例加载器类) 日志,App 模块的依赖完成初始化
[Nest] 21804 - 2024/12/23 13:28:35 LOG [RoutesResolver] AppController {/}: +9ms
RoutesResolver(路由解析器类) 日志,App 控制器建立了 ‘/’ 这个路由
[Nest] 21804 - 2024/12/23 13:28:35 LOG [RouterExplorer] Mapped {/, GET} route +2ms
RouterExplorer(路由管理器类) 日志,完成了 'GET /' 路由的映射
[Nest] 21804 - 2024/12/23 13:28:35 LOG [NestApplication] Nest application successfully started +3ms
NestApplication(Nest 应用程序类) 日志,Nest 应用成功启动
所以现在,浏览器就可以访问/ 这个路由了
Hello, world
Nest 应用默认的端口是 3000,打开浏览器,访问 localhost:3000,就可以看到如下界面

接下来我们去看下源码,看下 NestJS 是如何将这个 Hello, World 响应给浏览器的
分析 Hello, World
下面是刚刚所创建的 Nest 项目的目录结构

我们先来关注下 src
目录,它下面有五个 .ts
文件,分别是:
- app.controller.spec.ts:App 控制器的单元测试文件
- app.controller.ts:App 模块的控制器
- app.module.ts:App 模块,也是 Nest 应用的根模块
- app.service.ts:App 模块的服务层代码
- main.ts:Nest 应用入口文件,用来创建 Nest 应用实例和启动应用
从 main.ts 看起
打开 src/main.ts
,这是 Nest 应用的入口文件。代码很简单
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
该文件封装了一个 bootstrap 函数,用于创建 Nest 应用。内部调用 NestFactory 工厂类的 create 方法,将 AppModule 传入,创建应用实例。最后应用调用 listen 方法,监听 3000 端口,完成 web 服务的启动。
如果你写过 Vue ,可以将此文件和 Vue 项目的入口文件 main.js
做一个类比。NestFactory.create
好比是 createApp 方法,AppModule 模块好比是 App.vue
根组件。
app.module.ts
Nest 应用是以模块 Module 为单元的。模块有两个核心成员,控制器和提供者。可以将模块理解为前端 Vue 项目中的组件。 app.module.ts
导出一个 AppModule 类,是 Nest 应用的根模块,就好比是 Vue 应用中的根组件。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
在该文件中,导入了 App 模块的控制器 AppController 和服务 AppService,然后通过装饰器(类似于 Java 中的注解) @Module
,将 AppModule 类声明为一个模块。
装饰器 @Module
接收了几个属性, controllers 和 providers。前者接收控制器,后者接收提供者,Nest 中提供者有很多中,代码中的 AppService 是提供者的一种。通过装饰器和这两个属性,一个模块就能将控制器和服务组织到一起。
app.controller.ts
这是 App 模块的控制器层代码,用来接收用户请求,调用服务层处理后,再将结果返回给客户端。
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
它首先导入了 Nestjs 核心包提供的两个装饰器,然后导入了 App 模块的服务类。通过 @Controller
装饰器,将 AppController
类声明为一个控制器。代码中类的构造方法是一种简写模式,作用是将 AppService 服务类的实例挂载到了控制器的实例上,并且还是私有成员,用伪代码表示就是
class AppController {
constructor() {
this.appService = new AppService()
}
}
但是实际上 AppService 服务类并不是在这里实例化的,而是作为依赖交给依赖注入容器的去管理的。
所以在类的成员方法中就可以直接调用 this.appService
了。
然后又使用了 @Get
装饰器声明了 getHello 方法,表示此方法用于处理 HHTP 的 GET请求。@Controller
和 @Get
都可以接收字符串类型的参数用来拼接路由,比如 @Controller('news')
和 @Get('list')
,拼接出来的路由就是 /news/list。示例代码中装饰器都省略了参数,默认为空字符串,所对应的路由就是根路由 /
。就好比 Express 中:
app.get('/', getHello)
app.get('/news/list', getNewsList)
getHello 方法内部调用了 App 服务层的 getHello
方法,所以接下来就该去看看 app.service.ts
了。
app.service.ts
这是 AppModule 的服务层文件,也是真正处理业务的地方。
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
该文件导入了一个 @Injectable
装饰器,它将 AppService 类型声明为了“提供者”。Nest 中有很多种提供者,这里的“服务”就是一种最常用的提供者。这里涉及到依赖注入的概念,提供者在依赖注入中的角色就是就是可以被注入到容器中的类。
这段代码可以先简单理解为使用了这个装饰器之后,AppService 类的实例可以直接在控制器中使用,而无需手动导入和实例化。
AppService 类有一个 getHello 方法,返回 Hello, World! 字符串,这就是我们在浏览器中看到的那个。它返回的字符串,交给了 App 控制器,控制器又返回给了浏览器,至此,一个完整的流程就走完了。
