首页 / NestJS 入门教程 / 项目结构解析

NestJS 入门教程

项目结构解析

本教程共 47 篇 · 第 4 篇 · 更新于 2026-08-09 · 约 9 分钟阅读

NestJS项目结构目录组织命名规范CLI配置文件

本节目标:搞清楚 NestJS 项目里每个文件、每个目录是干嘛的,学会按规范组织自己的代码。

默认项目结构

nest new 创建项目后,你会看到这样一堆文件:

my-project/
├── node_modules/
├── src/
│   ├── app.controller.spec.ts
│   ├── app.controller.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test/
│   ├── app.e2e-spec.ts
│   └── jest-e2e.json
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── nest-cli.json
├── package.json
├── tsconfig.build.json
└── tsconfig.json

文件不少,但核心就 src/ 下的那几个。其余的要么是配置文件,要么是测试文件。

src 目录:代码都在这

src/ 是源代码目录,你写的所有业务代码都放这里。

src/
├── main.ts                 # 应用入口
├── app.module.ts           # 根模块
├── app.controller.ts       # 根控制器
├── app.controller.spec.ts  # 控制器的单元测试
└── app.service.ts          # 根服务

每个文件的职责:

main.ts — 应用的启动入口。创建 NestJS 应用实例,配置全局设置,启动 HTTP 服务器。上一章已经看过了。

app.module.ts — 根模块,整个应用的”总装配图”。所有功能模块都挂在它下面。

app.controller.ts — 根控制器,处理根路径 / 的请求。脚手架默认给了一个返回 “Hello World!” 的路由。

app.service.ts — 根服务,包含业务逻辑。脚手架默认给了一个 getHello() 方法。

app.controller.spec.ts — 控制器的单元测试文件。NestJS 很重视测试,所以连脚手架都帮你把测试文件生成好了。

Tip

如果你不需要测试文件,生成时加 --no-spec 参数就行:nest g service users --no-spec

配置文件逐个看

nest-cli.json

Nest CLI 的配置文件:

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

几个关键配置:

配置项说明
sourceRoot源代码目录,默认 src
collectionCLI 生成代码时用的模板集
compilerOptions.deleteOutDir构建前是否清空输出目录
Note

deleteOutDir: true 这个配置很实用。每次 nest build 时会先清空 dist/ 目录,避免残留旧文件。

tsconfig.json

TypeScript 的配置文件。NestJS 脚手架帮你配好了关键选项:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2021",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": true,
    "noImplicitAny": true,
    "strictBindCallApply": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true
  }
}

有两个配置是 NestJS 必须的,千万别删:

  • emitDecoratorMetadata: true — 发射装饰器的元数据,NestJS 的依赖注入靠它工作
  • experimentalDecorators: true — 启用装饰器语法
Tip

很多人遇到”依赖注入不生效”的问题,最后发现是这两个选项没开。记住,NestJS 项目里这俩是必须的。

tsconfig.build.json

这个是构建专用的 TS 配置,继承自 tsconfig.json,额外排除了测试文件:

{
  "extends": "./tsconfig.json",
  "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

平时不用改它。

.prettierrc

代码格式化配置。NestJS 默认用 Prettier 来统一代码风格。

.eslintrc.js

代码规范检查配置。默认用 ESLint 来检查代码质量问题。

test 目录:端到端测试

test/
├── app.e2e-spec.ts    # E2E 测试文件
└── jest-e2e.json      # Jest E2E 配置

E2E 测试(End-to-End)是模拟真实用户请求来测试整个应用。和单元测试不同,单元测试测的是单个类或方法,E2E 测的是完整的请求链路。

跑 E2E 测试:

npm run test:e2e

命名规范

NestJS 有一套严格的文件命名规范。遵循这套规范,别人一看文件名就知道文件里是什么。

文件命名

类型文件名格式示例
模块*.module.tsusers.module.ts
控制器*.controller.tsusers.controller.ts
服务*.service.tsusers.service.ts
DTO*.dto.tscreate-user.dto.ts
实体*.entity.tsuser.entity.ts
接口*.interface.tsuser.interface.ts
守卫*.guard.tsjwt-auth.guard.ts
中间件*.middleware.tslogger.middleware.ts
管道*.pipe.tsvalidation.pipe.ts
拦截器*.interceptor.tslogging.interceptor.ts
过滤器*.filter.tshttp-exception.filter.ts

类命名

类名用 PascalCase,加上对应的后缀:

类型类名格式示例
模块XxxModuleUsersModule
控制器XxxControllerUsersController
服务XxxServiceUsersService
DTOXxxDtoCreateUserDto
守卫XxxGuardJwtAuthGuard
Note

这些不是强制要求,但强烈建议遵守。团队协作时,统一的命名规范能省掉很多沟通成本。

推荐的目录组织

小项目用默认的 src/ 平铺就够了。项目一大,你需要更好的组织方式。

推荐按”功能模块”来组织目录:

src/
├── main.ts
├── app.module.ts

├── common/                    # 公共模块
│   ├── decorators/            # 自定义装饰器
│   ├── filters/               # 全局异常过滤器
│   ├── guards/                # 全局守卫
│   ├── interceptors/          # 全局拦截器
│   ├── middleware/             # 全局中间件
│   └── pipes/                 # 全局管道

├── config/                    # 配置相关
│   ├── database.config.ts
│   └── configuration.ts

├── modules/                   # 功能模块
│   ├── auth/                  # 认证模块
│   │   ├── auth.module.ts
│   │   ├── auth.controller.ts
│   │   ├── auth.service.ts
│   │   ├── dto/
│   │   │   ├── login.dto.ts
│   │   │   └── register.dto.ts
│   │   └── strategies/
│   │       └── jwt.strategy.ts
│   │
│   ├── users/                 # 用户模块
│   │   ├── users.module.ts
│   │   ├── users.controller.ts
│   │   ├── users.service.ts
│   │   ├── dto/
│   │   │   ├── create-user.dto.ts
│   │   │   └── update-user.dto.ts
│   │   └── entities/
│   │       └── user.entity.ts
│   │
│   └── products/              # 产品模块
│       ├── products.module.ts
│       ├── products.controller.ts
│       └── products.service.ts

└── database/                  # 数据库相关
    ├── migrations/
    └── seeds/

核心思路:

  • common/ 放全局共享的东西(过滤器、守卫、管道等)
  • config/ 放配置文件
  • modules/ 按业务功能划分模块,每个模块一个目录
  • database/ 放数据库迁移和种子数据
Tip

不用一开始就搞这么复杂。项目刚开始时简单组织就行,等功能多起来了再逐步重构。别过度设计。

单个模块的目录结构

一个功能模块内部,推荐这样组织:

users/
├── users.module.ts           # 模块定义(必须有)
├── users.controller.ts       # 控制器
├── users.service.ts          # 服务
├── dto/                      # 数据传输对象
│   ├── create-user.dto.ts
│   └── update-user.dto.ts
├── entities/                 # 数据实体
│   └── user.entity.ts
└── interfaces/               # TypeScript 接口
    └── user.interface.ts

不是每个模块都需要这些子目录。简单的模块可能只有一个 module、一个 controller、一个 service,三个文件就够了。

用 CLI 快速生成代码

Nest CLI 能帮你生成各种文件,不用手动创建:

# 生成模块
nest g module users

# 生成控制器
nest g controller users

# 生成服务
nest g service users

# 生成守卫
nest g guard auth/jwt

# 生成拦截器
nest g interceptor logging

# 生成过滤器
nest g filter http-exception

# 生成管道
nest g pipe validation

# 生成装饰器
nest g decorator current-user

# 生成中间件
nest g middleware logger

常用选项:

# 不生成测试文件
nest g service users --no-spec

# 注册到指定模块
nest g controller users --module app
Note

用 CLI 生成模块时,Nest 会自动把它注册到根模块的 imports 里。手动创建模块的话,别忘了自己注册。

代码分层

NestJS 推荐一个清晰的分层架构:

请求 → Controller → Service → Repository → 数据库
              ↓          ↓
             DTO       Entity
  • Controller:接收请求,提取参数,调用 Service,返回响应
  • Service:处理业务逻辑,调用 Repository
  • Repository:操作数据库(用 TypeORM、Prisma 等)
  • DTO:定义请求参数的结构
  • Entity:定义数据库表的结构

每一层只干自己的事,不越界。Controller 不直接操作数据库,Service 不直接处理 HTTP 请求。

小结

NestJS 的项目结构看着文件多,但规律很清晰:

  • src/ 下写代码,按功能模块组织
  • 文件命名有规范,看名字就知道类型
  • CLI 帮你生成大部分样板代码
  • 分层架构让代码职责清晰

掌握了项目结构,后面学模块、控制器、服务这些概念时,你就知道它们分别放在哪里了。