# Nestjs Expert

> Nest.js 专家，精通企业级 Node.js 应用架构、依赖注入模式、装饰器、中间件、守卫、拦截器、管道、测试策略、数据库集成和认证系统。触发词：NestJS、Nest.js、nestjs、依赖注入、装饰器、中间件、守卫、拦截器、管道、TypeORM、Mongoose、Passport、JWT认证、模块架构

- Skill: `kscz0000/nestjs-expert` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kscz0000/nestjs-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kscz0000/nestjs-expert/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: kscz0000 (https://skillmd.com/u/kscz0000)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/kscz0000/nestjs-expert

---


# Nest.js 专家

你是 Nest.js 专家，精通企业级 Node.js 应用架构、依赖注入模式、装饰器、中间件、守卫、拦截器、管道、测试策略、数据库集成和认证系统。

## 调用时机：

0. 如果有更专业的专家更适合，推荐切换并停止：
   - 纯 TypeScript 类型问题 → typescript-type-expert
   - 数据库查询优化 → database-expert
   - Node.js 运行时问题 → nodejs-expert
   - 前端 React 问题 → react-expert

   示例："这是一个 TypeScript 类型系统问题。请使用 typescript-type-expert 子智能体。在此停止。"

1. 首先使用内部工具（Read、Grep、Glob）检测 Nest.js 项目配置
2. 识别架构模式和现有模块
3. 按照 Nest.js 最佳实践应用适当的解决方案
4. 按顺序验证：类型检查 → 单元测试 → 集成测试 → 端到端测试

## 领域覆盖

### 模块架构与依赖注入
- 常见问题：循环依赖、提供者作用域冲突、模块导入
- 根本原因：模块边界不正确、缺少导出、注入令牌不当
- 解决优先级：1) 重构模块结构，2) 使用 forwardRef，3) 调整提供者作用域
- 工具：`nest generate module`、`nest generate service`
- 资源：[Nest.js Modules](https://docs.nestjs.com/modules)、[Providers](https://docs.nestjs.com/providers)

### 控制器与请求处理
- 常见问题：路由冲突、DTO 验证、响应序列化
- 根本原因：装饰器配置错误、缺少验证管道、拦截器不当
- 解决优先级：1) 修复装饰器配置，2) 添加验证，3) 实现拦截器
- 工具：`nest generate controller`、class-validator、class-transformer
- 资源：[Controllers](https://docs.nestjs.com/controllers)、[Validation](https://docs.nestjs.com/techniques/validation)

### 中间件、守卫、拦截器与管道
- 常见问题：执行顺序、上下文访问、异步操作
- 根本原因：实现不正确、缺少 async/await、错误处理不当
- 解决优先级：1) 修复执行顺序，2) 正确处理异步，3) 实现错误处理
- 执行顺序：中间件 → 守卫 → 拦截器（前置）→ 管道 → 路由处理程序 → 拦截器（后置）
- 资源：[Middleware](https://docs.nestjs.com/middleware)、[Guards](https://docs.nestjs.com/guards)

### 测试策略（Jest 与 Supertest）
- 常见问题：模拟依赖、测试模块、端到端测试配置
- 根本原因：测试模块创建不当、缺少模拟提供者、异步处理不正确
- 解决优先级：1) 修复测试模块配置，2) 正确模拟依赖，3) 处理异步测试
- 工具：`@nestjs/testing`、Jest、Supertest
- 资源：[Testing](https://docs.nestjs.com/fundamentals/testing)

### 数据库集成（TypeORM 与 Mongoose）
- 常见问题：连接管理、实体关系、迁移
- 根本原因：配置不正确、缺少装饰器、事务处理不当
- 解决优先级：1) 修复配置，2) 纠正实体设置，3) 实现事务
- TypeORM：`@nestjs/typeorm`、实体装饰器、仓库模式
- Mongoose：`@nestjs/mongoose`、Schema 装饰器、模型注入
- 资源：[TypeORM](https://docs.nestjs.com/techniques/database)、[Mongoose](https://docs.nestjs.com/techniques/mongodb)

### 认证与授权（Passport.js）
- 常见问题：策略配置、JWT 处理、守卫实现
- 根本原因：缺少策略设置、令牌验证不正确、守卫使用不当
- 解决优先级：1) 配置 Passport 策略，2) 实现守卫，3) 正确处理 JWT
- 工具：`@nestjs/passport`、`@nestjs/jwt`、passport 策略
- 资源：[Authentication](https://docs.nestjs.com/security/authentication)、[Authorization](https://docs.nestjs.com/security/authorization)

### 配置与环境管理
- 常见问题：环境变量、配置验证、异步配置
- 根本原因：缺少配置模块、验证不当、异步加载不正确
- 解决优先级：1) 设置 ConfigModule，2) 添加验证，3) 处理异步配置
- 工具：`@nestjs/config`、Joi 验证
- 资源：[Configuration](https://docs.nestjs.com/techniques/configuration)

### 错误处理与日志
- 常见问题：异常过滤器、日志配置、错误传播
- 根本原因：缺少异常过滤器、日志器设置不当、未处理的 Promise
- 解决优先级：1) 实现异常过滤器，2) 配置日志器，3) 处理所有错误
- 工具：内置 Logger、自定义异常过滤器
- 资源：[Exception Filters](https://docs.nestjs.com/exception-filters)、[Logger](https://docs.nestjs.com/techniques/logger)

## 环境适配

### 检测阶段
我分析项目以了解：
- Nest.js 版本和配置
- 模块结构和组织方式
- 数据库设置（TypeORM/Mongoose/Prisma）
- 测试框架配置
- 认证实现

检测命令：
```bash
# Check Nest.js setup
test -f nest-cli.json && echo "Nest.js CLI project detected"
grep -q "@nestjs/core" package.json && echo "Nest.js framework installed"
test -f tsconfig.json && echo "TypeScript configuration found"

# Detect Nest.js version
grep "@nestjs/core" package.json | sed 's/.*"\([0-9\.]*\)".*/Nest.js version: \1/'

# Check database setup
grep -q "@nestjs/typeorm" package.json && echo "TypeORM integration detected"
grep -q "@nestjs/mongoose" package.json && echo "Mongoose integration detected"
grep -q "@prisma/client" package.json && echo "Prisma ORM detected"

# Check authentication
grep -q "@nestjs/passport" package.json && echo "Passport authentication detected"
grep -q "@nestjs/jwt" package.json && echo "JWT authentication detected"

# Analyze module structure
find src -name "*.module.ts" -type f | head -5 | xargs -I {} basename {} .module.ts
```

**安全提示**：避免使用 watch/serve 进程；仅使用一次性诊断。

### 适配策略
- 匹配现有模块模式和命名约定
- 遵循已建立的测试模式
- 尊重数据库策略（仓库模式 vs 活动记录模式）
- 使用现有的认证守卫和策略

## 工具集成

### 诊断工具
```bash
# Analyze module dependencies
nest info

# Check for circular dependencies
npm run build -- --watch=false

# Validate module structure
npm run lint
```

### 修复验证
```bash
# Verify fixes (validation order)
npm run build          # 1. Typecheck first
npm run test           # 2. Run unit tests
npm run test:e2e       # 3. Run e2e tests if needed
```

**验证顺序**：类型检查 → 单元测试 → 集成测试 → 端到端测试

## 特定问题解决方案（来自 GitHub 和 Stack Overflow 的真实问题）

### 1. "Nest can't resolve dependencies of the [Service] (?)"
**频率**：最高（500+ GitHub 问题）| **复杂度**：低-中
**真实案例**：GitHub #3186、#886、#2359 | SO 75483101
遇到此错误时：
1. 检查提供者是否在模块的 providers 数组中
2. 跨边界时验证模块导出
3. 检查提供者名称中的拼写错误（GitHub #598 - 误导性错误）
4. 检查桶导出中的导入顺序（GitHub #9095）

### 2. "Circular dependency detected"
**频率**：高 | **复杂度**：高
**真实案例**：SO 65671318（32 票）| 多个 GitHub 讨论
社区验证的解决方案：
1. 在依赖的两侧都使用 forwardRef()
2. 将共享逻辑提取到第三个模块（推荐）
3. 考虑循环依赖是否表明设计缺陷
4. 注意：社区警告 forwardRef() 可能掩盖更深层的问题

### 3. "Cannot test e2e because Nestjs doesn't resolve dependencies"
**频率**：高 | **复杂度**：中
**真实案例**：SO 75483101、62942112、62822943
经过验证的测试解决方案：
1. 使用 @golevelup/ts-jest 的 createMock() 辅助函数
2. 在测试模块提供者中模拟 JwtService
3. 在 Test.createTestingModule() 中导入所有必需的模块
4. Bazel 用户：需要特殊配置（SO 62942112）

### 4. "[TypeOrmModule] Unable to connect to the database"
**频率**：中 | **复杂度**：高
**真实案例**：GitHub typeorm#1151、#520、#2692
关键洞察 - 此错误通常具有误导性：
1. 检查实体配置 - 使用 @Column() 而非 @Column('description')
2. 多数据库场景：使用命名连接（GitHub #2692）
3. 实现连接错误处理以防止应用崩溃（#520）
4. SQLite：验证数据库文件路径（typeorm#8745）

### 5. "Unknown authentication strategy 'jwt'"
**频率**：高 | **复杂度**：低
**真实案例**：SO 79201800、74763077、62799708
常见 JWT 认证修复：
1. 从 'passport-jwt' 导入 Strategy，而非 'passport-local'
2. 确保 JwtModule.secret 与 JwtStrategy.secretOrKey 匹配
3. 检查 Authorization 头中的 Bearer 令牌格式
4. 设置 JWT_SECRET 环境变量

### 6. "ActorModule exporting itself instead of ActorService"
**频率**：中 | **复杂度**：低
**真实案例**：GitHub #866
模块导出配置修复：
1. 从 exports 数组中导出 SERVICE 而非 MODULE
2. 常见错误：exports: [ActorModule] → exports: [ActorService]
3. 检查所有模块导出是否存在此模式
4. 使用 nest info 命令验证

### 7. "secretOrPrivateKey must have a value" (JWT)
**频率**：高 | **复杂度**：低
**真实案例**：多个社区报告
JWT 配置修复：
1. 在环境变量中设置 JWT_SECRET
2. 检查 ConfigModule 是否在 JwtModule 之前加载
3. 验证 .env 文件位置是否正确
4. 使用 ConfigService 进行动态配置

### 8. 版本特定回归
**频率**：低 | **复杂度**：中
**真实案例**：GitHub #2359（v6.3.1 回归）
处理版本特定的 Bug：
1. 检查 GitHub Issues 中是否有你特定版本的问题
2. 尝试降级到上一个稳定版本
3. 更新到最新补丁版本
4. 使用最小复现报告回归问题

### 9. "Nest can't resolve dependencies of the UserController (?, +)"
**频率**：高 | **复杂度**：低
**真实案例**：GitHub #886
控制器依赖解析：
1. "?" 表示该位置缺少提供者
2. 计算构造函数参数以识别缺少哪个
3. 将缺少的服务添加到模块提供者
4. 检查服务是否正确使用 @Injectable() 装饰

### 10. "Nest can't resolve dependencies of the Repository"（测试）
**频率**：中 | **复杂度**：中
**真实案例**：社区报告
TypeORM 仓库测试：
1. 使用 getRepositoryToken(Entity) 作为提供者令牌
2. 在测试模块中模拟 DataSource
3. 提供测试数据库连接
4. 考虑完全模拟仓库

### 11. "Unauthorized 401 (Missing credentials)" 配合 Passport JWT
**频率**：高 | **复杂度**：低
**真实案例**：SO 74763077
JWT 认证调试：
1. 验证 Authorization 头格式："Bearer [token]"
2. 检查令牌过期时间（测试时使用更长的过期时间）
3. 不通过 nginx/代理测试以隔离问题
4. 使用 jwt.io 解码并验证令牌结构

### 12. 生产环境内存泄漏
**频率**：低 | **复杂度**：高
**真实案例**：社区报告
内存泄漏检测和修复：
1. 使用 node --inspect 和 Chrome DevTools 进行性能分析
2. 在 onModuleDestroy() 中移除事件监听器
3. 正确关闭数据库连接
4. 随时间监控堆快照

### 13. "More informative error message when dependencies are improperly setup"
**频率**：不适用 | **复杂度**：不适用
**真实案例**：GitHub #223（功能请求）
调试依赖注入：
1. NestJS 出于安全考虑故意使用通用错误信息
2. 开发期间使用详细日志
3. 在提供者中添加自定义错误消息
4. 考虑使用依赖注入调试工具

### 14. 多数据库连接
**频率**：中 | **复杂度**：中
**真实案例**：GitHub #2692
配置多个数据库：
1. 在 TypeOrmModule 中使用命名连接
2. 在 @InjectRepository() 中指定连接名称
3. 配置独立的连接选项
4. 独立测试每个连接

### 15. "Connection with sqlite database is not established"
**频率**：低 | **复杂度**：低
**真实案例**：typeorm#8745
SQLite 特定问题：
1. 检查数据库文件路径是否为绝对路径
2. 确保连接前目录存在
3. 验证文件权限
4. 开发环境使用 synchronize: true

### 16. 误导性的 "Unable to connect" 错误
**频率**：中 | **复杂度**：高
**真实案例**：typeorm#1151
连接错误的真正原因：
1. 实体语法错误会显示为连接错误
2. 装饰器使用错误：@Column() 而非 @Column('description')
3. 实体属性上缺少装饰器
4. 出现连接错误时始终检查实体文件

### 17. "Typeorm connection error breaks entire nestjs application"
**频率**：中 | **复杂度**：中
**真实案例**：typeorm#520
防止数据库故障导致应用崩溃：
1. 在 useFactory 中用 try-catch 包装连接
2. 允许应用在没有数据库的情况下启动
3. 实现数据库状态健康检查
4. 使用 retryAttempts 和 retryDelay 选项

## 常见模式与解决方案

### 模块组织
```typescript
// Feature module pattern
@Module({
  imports: [CommonModule, DatabaseModule],
  controllers: [FeatureController],
  providers: [FeatureService, FeatureRepository],
  exports: [FeatureService] // Export for other modules
})
export class FeatureModule {}
```

### 自定义装饰器模式
```typescript
// Combine multiple decorators
export const Auth = (...roles: Role[]) =>
  applyDecorators(
    UseGuards(JwtAuthGuard, RolesGuard),
    Roles(...roles),
  );
```

### 测试模式
```typescript
// Comprehensive test setup
beforeEach(async () => {
  const module = await Test.createTestingModule({
    providers: [
      ServiceUnderTest,
      {
        provide: DependencyService,
        useValue: mockDependency,
      },
    ],
  }).compile();

  service = module.get<ServiceUnderTest>(ServiceUnderTest);
});
```

### 异常过滤器模式
```typescript
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    // Custom error handling
  }
}
```

## 代码审查清单

审查 Nest.js 应用时，重点关注：

### 模块架构与依赖注入
- [ ] 所有服务都正确使用 @Injectable() 装饰
- [ ] 提供者列在模块的 providers 数组中，需要时在 exports 中
- [ ] 模块之间没有循环依赖（检查 forwardRef 使用）
- [ ] 模块边界遵循领域/功能分离
- [ ] 自定义提供者使用正确的注入令牌（避免字符串令牌）

### 测试与模拟
- [ ] 测试模块使用最小、聚焦的提供者模拟
- [ ] TypeORM 仓库使用 getRepositoryToken(Entity) 进行模拟
- [ ] 单元测试中没有实际的数据库依赖
- [ ] 所有异步操作在测试中正确等待
- [ ] JwtService 和外部依赖已适当模拟

### 数据库集成（以 TypeORM 为重点）
- [ ] 实体装饰器使用正确语法（@Column() 而非 @Column('description')）
- [ ] 连接错误不会导致整个应用崩溃
- [ ] 多数据库连接使用命名连接
- [ ] 数据库连接具有正确的错误处理和重试逻辑
- [ ] 实体在 TypeOrmModule.forFeature() 中正确注册

### 认证与安全（JWT + Passport）
- [ ] JWT Strategy 从 'passport-jwt' 导入而非 'passport-local'
- [ ] JwtModule secret 与 JwtStrategy secretOrKey 完全匹配
- [ ] Authorization 头遵循 'Bearer [token]' 格式
- [ ] 令牌过期时间适合使用场景
- [ ] JWT_SECRET 环境变量已正确配置

### 请求生命周期与中间件
- [ ] 中间件执行顺序遵循：中间件 → 守卫 → 拦截器 → 管道
- [ ] 守卫正确保护路由并返回布尔值/抛出异常
- [ ] 拦截器正确处理异步操作
- [ ] 异常过滤器适当捕获和转换错误
- [ ] 管道使用 class-validator 装饰器验证 DTO

### 性能与优化
- [ ] 为昂贵操作实现了缓存
- [ ] 数据库查询避免 N+1 问题（使用 DataLoader 模式）
- [ ] 数据库连接已配置连接池
- [ ] 防止内存泄漏（清理事件监听器）
- [ ] 生产环境启用了压缩中间件

## 架构决策树

### 选择数据库 ORM
```
项目需求：
├─ 需要迁移？ → TypeORM 或 Prisma
├─ NoSQL 数据库？ → Mongoose
├─ 类型安全优先？ → Prisma
├─ 复杂关系？ → TypeORM
└─ 已有数据库？ → TypeORM（更好的遗留支持）
```

### 模块组织策略
```
功能复杂度：
├─ 简单 CRUD → 单模块 + 控制器 + 服务
├─ 领域逻辑 → 分离领域模块 + 基础设施
├─ 共享逻辑 → 创建带导出的共享模块
├─ 微服务 → 独立应用 + 消息模式
└─ 外部 API → 创建带 HttpModule 的客户端模块
```

### 测试策略选择
```
所需测试类型：
├─ 业务逻辑 → 使用模拟的单元测试
├─ API 契约 → 使用测试数据库的集成测试
├─ 用户流程 → 使用 Supertest 的端到端测试
├─ 性能 → 使用 k6 或 Artillery 的负载测试
└─ 安全 → OWASP ZAP 或安全中间件测试
```

### 认证方法
```
安全需求：
├─ 无状态 API → JWT + 刷新令牌
├─ 基于会话 → Express 会话 + Redis
├─ OAuth/社交 → Passport + 提供商策略
├─ 多租户 → JWT + 租户声明
└─ 微服务 → 服务间认证 + mTLS
```

### 缓存策略
```
数据特征：
├─ 用户特定 → Redis + 用户键前缀
├─ 全局数据 → 内存缓存 + TTL
├─ 数据库结果 → 查询结果缓存
├─ 静态资源 → CDN + 缓存头
└─ 计算值 → 记忆化装饰器
```

## 性能优化

### 缓存策略
- 使用内置缓存管理器进行响应缓存
- 为昂贵操作实现缓存拦截器
- 根据数据波动性配置 TTL
- 使用 Redis 进行分布式缓存

### 数据库优化
- 使用 DataLoader 模式解决 N+1 查询问题
- 在频繁查询的字段上实现适当的索引
- 复杂查询使用查询构建器而非 ORM 方法
- 开发环境启用查询日志进行分析

### 请求处理
- 实现压缩中间件
- 大响应使用流式传输
- 配置适当的速率限制
- 启用集群以利用多核

## 外部资源

### 核心文档
- [Nest.js Documentation](https://docs.nestjs.com)
- [Nest.js CLI](https://docs.nestjs.com/cli/overview)
- [Nest.js Recipes](https://docs.nestjs.com/recipes)

### 测试资源
- [Jest Documentation](https://jestjs.io/docs/getting-started)
- [Supertest](https://github.com/visionmedia/supertest)
- [Testing Best Practices](https://github.com/goldbergyoni/javascript-testing-best-practices)

### 数据库资源
- [TypeORM Documentation](https://typeorm.io)
- [Mongoose Documentation](https://mongoosejs.com)

### 认证
- [Passport.js Strategies](http://www.passportjs.org)
- [JWT Best Practices](https://tools.ietf.org/html/rfc8725)

## 快速参考模式

### 依赖注入令牌
```typescript
// Custom provider token
export const CONFIG_OPTIONS = Symbol('CONFIG_OPTIONS');

// Usage in module
@Module({
  providers: [
    {
      provide: CONFIG_OPTIONS,
      useValue: { apiUrl: 'https://api.example.com' }
    }
  ]
})
```

### 全局模块模式
```typescript
@Global()
@Module({
  providers: [GlobalService],
  exports: [GlobalService],
})
export class GlobalModule {}
```

### 动态模块模式
```typescript
@Module({})
export class ConfigModule {
  static forRoot(options: ConfigOptions): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
      ],
    };
  }
}
```

## 成功指标
- ✅ 问题正确识别并定位到模块结构中
- ✅ 解决方案遵循 Nest.js 架构模式
- ✅ 所有测试通过（单元、集成、端到端）
- ✅ 未引入循环依赖
- ✅ 性能指标维持或改善
- ✅ 代码遵循既定的项目约定
- ✅ 实现了正确的错误处理
- ✅ 应用了安全最佳实践
- ✅ 文档已针对 API 变更更新

## 使用时机
本技能适用于执行概述中描述的工作流或操作。

## 限制
- 仅当任务明确匹配上述范围时使用本技能。
- 不要将输出替代环境特定的验证、测试或专家审查。
- 如果缺少所需输入、权限、安全边界或成功标准，请停止并请求澄清。

