1. NestJS 项目初始化:使用 CLI 创建项目、项目目录结构解析、核心文件介绍

NestJS 项目初始化的第一步是使用官方 CLI 工具快速搭建项目骨架。CLI 会自动生成标准化的目录结构、核心配置文件和基础模块,让开发者从零开始就能获得一个可运行、可扩展的 Node.js 后端应用。本节将演示 CLI 创建命令,解析生成后的目录结构,并深入介绍 main.ts 和 app.module.ts 两个核心文件。

1.1 使用 CLI 创建项目

确保已全局安装 @nestjs/cli,然后执行以下命令创建新项目:

# 全局安装 NestJS CLI(如未安装)
npm install -g @nestjs/cli

# 创建新项目,项目名称为 nest-auth-demo
nest new nest-auth-demo

CLI 会提示选择包管理器(npm / yarn / pnpm),选择后自动安装依赖。安装完成后,项目根目录下会生成以下核心文件与文件夹:

文件/目录 用途
src/ 应用源代码主目录,所有业务代码均放置于此
src/main.ts 应用入口文件,负责启动 HTTP 服务
src/app.module.ts 根模块,声明全局依赖、控制器、提供者
src/app.controller.ts 根控制器,处理基础路由请求
src/app.service.ts 根服务,封装业务逻辑
test/ 端到端测试文件目录
nest-cli.json NestJS CLI 构建与编译配置
tsconfig.json TypeScript 编译选项配置
package.json 项目依赖与脚本定义
提示:CLI 创建的默认项目已包含 @nestjs/core、@nestjs/common、rxjs 等核心依赖,无需手动安装。后续添加模块时,可使用 nest generate module <name> 命令保持目录结构一致。

1.2 项目目录结构解析

NestJS 遵循“模块化”与“分层”设计哲学,默认目录结构体现了清晰的关注点分离:

nest-auth-demo/
├── src/
│   ├── main.ts                 # 应用入口
│   ├── app.module.ts           # 根模块
│   ├── app.controller.ts       # 根控制器
│   ├── app.controller.spec.ts  # 根控制器单元测试
│   ├── app.service.ts          # 根服务
│   └── app.service.spec.ts     # 根服务单元测试
├── test/
│   ├── app.e2e-spec.ts         # 端到端测试
│   └── jest-e2e.json           # E2E 测试配置
├── node_modules/               # 依赖包(自动生成)
├── nest-cli.json               # CLI 配置
├── tsconfig.json               # TypeScript 配置
├── tsconfig.build.json         # 构建专用 TypeScript 配置
├── package.json                # 项目元数据
├── .eslintrc.js                # ESLint 规则
├── .prettierrc                 # Prettier 格式化配置
└── README.md                   # 项目说明

各目录与文件的职责可归纳为以下三层:

  • 入口层(main.ts):负责创建 Nest 应用实例、配置中间件、监听端口。
  • 模块层(app.module.ts):作为根模块,组织控制器、服务、子模块的依赖关系。
  • 业务层(app.controller.ts + app.service.ts):处理 HTTP 请求并返回响应,业务逻辑封装在 Service 中。
NestJS 项目目录结构分层图 NestJS 项目目录结构分层图 入口层 src/main.ts — 创建 NestFactory,启动 HTTP 服务 模块层 src/app.module.ts — 根模块,声明控制器、服务、子模块 业务层 src/app.controller.ts + src/app.service.ts — 路由处理与业务逻辑

1.3 核心文件介绍:main.ts

main.ts 是 NestJS 应用的启动入口,其核心职责包括:创建 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();

关键点解析:

  • NestFactory.create(AppModule):基于根模块创建 Nest 应用实例,内部完成依赖注入容器的初始化。
  • app.listen(3000):启动 HTTP 服务器,默认监听 3000 端口。可通过环境变量动态配置端口。
  • bootstrap():自执行异步函数,保证应用启动过程支持 await 语法。
安全测试视角:在后续章节中,我们会在 main.ts 中注册全局授权守卫、全局验证管道和 CORS 中间件。这些配置是授权测试与数据传输验证的基础设施。

1.4 核心文件介绍:app.module.ts

app.module.ts 是应用的根模块,使用 @Module() 装饰器声明模块元数据。默认代码如下:

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() 装饰器接受一个配置对象,包含四个核心属性:

属性 类型 说明
imports Array<Type<any>> 导入其他模块,使当前模块可使用被导入模块导出的提供者
controllers Array<Type<any>> 注册该模块下的控制器,处理入站请求
providers Array<Type<any>> 注册服务、工厂、守卫等提供者,由依赖注入容器管理
exports Array<Type<any>> 导出本模块的提供者,供其他模块使用(默认未出现)

根模块是整个应用的依赖注入起点。所有全局性的守卫、拦截器、管道、过滤器通常在此注册,或通过 @Global() 装饰器标记为全局模块。

注意:在授权测试场景中,app.module.ts 的 imports 数组会逐步加入 AuthModule、UserModule、DatabaseModule 等子模块。模块间的依赖关系直接影响授权守卫的作用域,务必保持模块导入顺序清晰。
main.ts 与 app.module.ts 协作关系图 main.ts 与 app.module.ts 协作关系 main.ts NestFactory.create(AppModule) app.listen(3000) app.module.ts @Module({ imports, controllers, providers }) export class AppModule 引用 协作流程 1. main.ts 调用 NestFactory.create(AppModule),传入根模块类 2. NestJS 内部解析 AppModule 的 @Module 元数据,构建依赖注入容器 3. 容器就绪后,main.ts 调用 app.listen() 启动 HTTP 服务

1.5 启动验证

项目初始化完成后,执行以下命令验证应用是否正常运行:

# 开发模式启动(热重载)
npm run start:dev

# 终端输出示例
[Nest] 12345  - 2025/01/15 10:00:00     LOG [NestFactory] Starting Nest application...
[Nest] 12345  - 2025/01/15 10:00:00     LOG [InstanceLoader] AppModule dependencies initialized
[Nest] 12345  - 2025/01/15 10:00:00     LOG [RoutesResolver] AppController {/}:
[Nest] 12345  - 2025/01/15 10:00:00     LOG [RouterExplorer] Mapped {GET /} route
[Nest] 12345  - 2025/01/15 10:00:00     LOG [NestApplication] Nest application successfully started

访问 http://localhost:3000,浏览器应返回 Hello World! 字符串,表明项目初始化成功。

最佳实践:建议在项目初期就将 main.ts 中的端口号提取到环境变量(如 process.env.PORT),并使用 @nestjs/config 模块统一管理配置。这为后续的授权测试环境切换和数据传输验证提供灵活性。