写给有 Vue/React 基础、但零后端经验的开发者。
目标:从零搭建 NestJS 项目,理解项目结构,跑通第一个接口。
一、NestJS 是什么?为什么选它?
一句话定义:NestJS 是一个用 TypeScript 构建的 Node.js 后端框架,专门用来写企业级服务端应用。
如果你熟悉前端,可以这样类比:
| 前端(Vue/React) | 后端(NestJS) |
|---|---|
| 组件(Component) | 控制器(Controller) |
| 状态管理(Vuex/Pinia) | 服务(Service) |
| 路由(Router) | 路由(Controller 里的装饰器) |
| 页面入口(App.vue) | 模块(Module) |
为什么选 NestJS?
- 强类型:天生 TypeScript,代码有类型约束,重构不怕炸。
- 架构清晰:强制你按 Controller → Service → Module 分层,不会写成"一坨屎山"。
- 企业级:内置依赖注入、模块化、异常处理等企业级特性,开箱即用。
- 生态好:和 Angular 同宗同源,装饰器写法几乎一样;同时支持 Express 和 Fastify。
二、环境准备
前置要求:
- Node.js >= 16(推荐 18+)
- npm 或 yarn
安装 NestJS CLI(脚手架工具):
bash
npm install -g @nestjs/cli
验证安装:
nest --version
三、创建第一个项目
nest new nestjs-enterprise-todo
选择包管理器时选 npm 即可。
创建完成后进入项目:
bash
cd nestjs-enterprise-todo
npm run start:dev
打开浏览器访问 http://localhost:3000,看到 Hello World! 就说明成功了。
四、项目结构详解
nestjs-enterprise-todo/
├── src/
│ ├── app.controller.ts # 控制器:处理 HTTP 请求
│ ├── app.controller.spec.ts # 控制器的单元测试
│ ├── app.module.ts # 根模块:项目的入口模块
│ ├── app.service.ts # 服务:处理业务逻辑
│ └── main.ts # 应用入口:启动 HTTP 服务器
├── test/ # 端到端测试
├── nest-cli.json # NestJS CLI 配置
├── tsconfig.json # TypeScript 配置
└── package.json # 依赖管理
核心文件逐个拆解:
main.ts ------ 应用入口
TypeScript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// 创建 NestJS 应用实例,AppModule 是根模块
const app = await NestFactory.create(AppModule);
// 监听 3000 端口
await app.listen(3000);
}
bootstrap();
类比前端 :main.ts 就像 Vue 的 main.js,是整个应用的启动入口。
app.module.ts ------ 根模块
TypeScript
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [], // 导入其他模块
controllers: [AppController], // 注册控制器
providers: [AppService], // 注册服务
})
export class AppModule {}
类比前端 :@Module() 就像 Vue 的 App.vue,是整个应用的"总装车间",把所有零件组装在一起。
app.controller.ts ------ 控制器
TypeScript
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller() // 声明这是一个控制器
export class AppController {
constructor(private readonly appService: AppService) {}
@Get() // 声明这个方法响应 GET 请求
getHello(): string {
return this.appService.getHello();
}
}
类比前端:Controller 就像 Vue 的组件,负责"接收用户操作,调用服务,返回结果"。
app.service.ts ------ 服务
TypeScript
import { Injectable } from '@nestjs/common';
@Injectable() // 声明这个类可以被依赖注入容器管理
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
类比前端:Service 就像 Pinia/Vuex 里的 action,负责处理具体的业务逻辑。
五、核心概念速览
NestJS 有四大核心概念,后面会逐个深入,这里先建立整体认知:
| 概念 | 作用 | 前端类比 |
|---|---|---|
| Controller | 接收 HTTP 请求,调用 Service,返回响应 | Vue 组件 |
| Service | 处理业务逻辑(查数据库、调接口等) | Pinia action |
| Module | 组织和管理 Controller、Service | App.vue / 路由模块 |
| DI(依赖注入) | 自动创建和管理对象,解耦组件之间的依赖 | provide/inject |
六、动手:写第一个自定义接口
打开 app.controller.ts,加一个新接口:
TypeScript
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();
}
// 新增:GET /user
@Get('user')
getUser() {
return {
name: '张三',
age: 25,
role: '前端工程师',
};
}
}
保存后,start:dev 会自动热重载。
打开浏览器访问 http://localhost:3000/user,你会看到:
javascript
{
"name": "张三",
"age": 25,
"role": "前端工程师"
}
恭喜,你的第一个后端接口写完了。
七、常见报错与解决方案
报错 1:nest: command not found
原因:NestJS CLI 没有全局安装。
解决
npm install -g @nestjs/cli
报错 2:端口 3000 被占用
原因:另一个程序已经占用了 3000 端口。
解决:在 main.ts 中换一个端口:
await app.listen(3001);
报错 3:修改代码后没有热重载
原因:你可能用的是 npm run start 而不是 npm run start:dev。
解决:用 npm run start:dev,它会监听文件变化并自动重启。
八、本篇总结
- NestJS 是一个 TypeScript 后端框架,架构清晰,适合企业级开发。
- 项目核心文件:
main.ts(入口)、app.module.ts(模块)、app.controller.ts(控制器)、app.service.ts(服务)。 - 四大核心概念:Controller、Service、Module、DI。
- 写一个接口只需要:在 Controller 里加一个方法,贴上
@Get()装饰器。
下一篇预告 :深入理解依赖注入(DI)------NestJS 最核心的机制,搞懂 @Injectable()、@Module()、DI 容器到底在干什么。