惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
罗磊的独立博客
M
MIT News - Artificial intelligence
G
Google Developers Blog
V
V2EX
D
Docker
博客园_首页
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
WordPress大学
WordPress大学
T
Tailwind CSS Blog
博客园 - 司徒正美
J
Java Code Geeks
L
LangChain Blog
博客园 - 三生石上(FineUI控件)
B
Blog RSS Feed
博客园 - 【当耐特】
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
P
Proofpoint News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - Franky

木灵鱼儿

18 NestJS 基于 Docker 的 NestJS + Prisma + Playwright 生产环境容器化实践 - 木灵鱼儿 VS Code BYOK 配置生成器 - 木灵鱼儿 2026 最新禁止浏览器密码管理器弹出教程 - 木灵鱼儿 16 NestJS 企业级 RBAC 权限控制体系 - 木灵鱼儿 15 NestJS 统一响应体设计(信封模式) - 木灵鱼儿 14 NestJS 生产级错误过滤方案 - 木灵鱼儿 13 NestJS 集成 TypeORM 完全指南 - 木灵鱼儿 12 NestJS 集成 Prisma ORM 完全指南(Prisma v7) - 木灵鱼儿 11 NestJS 注册与登录接口的密码安全设计 - 木灵鱼儿 10 NestJS JWT 身份验证完全指南 - 木灵鱼儿 09 NestJS 使用 @nestjs-swagger 生成 API 文档 - 木灵鱼儿 08 NestJS DTO 校验、Entity 脱敏与 Mapped Types 实战(TypeORM & Prisma) - 木灵鱼儿 07 NestJS 使用Caching缓存(cache-manager) - 木灵鱼儿 06 NestJS 使用Redis - 木灵鱼儿 05 Nestjs 高性能构建之SWC与Typescript7选型 - 木灵鱼儿 04 Nestjs API版本控制策略 - 木灵鱼儿 NestJS 正确处理日志 - 木灵鱼儿 NestJS config模块扩展用法.md - 木灵鱼儿 宝塔如何给网站一次性绑定两个域名 - 木灵鱼儿 NestJS 环境变量与配置管理(Config 模块) - 木灵鱼儿 如何使用 FNM 自动切换不同项目的 Node.js 版本 - 木灵鱼儿 如何使用 Node.js Corepack 自动锁定和切换项目包管理器版本 - 木灵鱼儿 日常开发中的 void:从忽略 Promise 到理解 JavaScript 历史写法 - 木灵鱼儿 git 进阶指南:如何用 Git Worktree 完美应对紧急 Bug 与多分支联调 - 木灵鱼儿 了解并解决 Git 大小写“无感”的幽灵 Bug - 木灵鱼儿 从零开始:手把手教你封装一个企业级 Axios 请求模块 - 木灵鱼儿 03-Vue Query 高级进阶:应对复杂业务场景的硬核套路 - 木灵鱼儿 02-Vue Query 快速入门:从零构建你的第一个声明式查询 - 木灵鱼儿 01-异步状态管理新范式:为什么在 Vue 3 中使用 vue-query? - 木灵鱼儿 git 如何将所有历史提交合并为一条 - 木灵鱼儿
17 NestJS 使用 CoreModule 实现基础设施与业务域的彻底解耦 ...
木灵鱼儿 · 2026-09-18 · via 木灵鱼儿

前言

刚用 nest new 初始化的项目,AppModule 往往只有十几行。但随着项目走向生产环境,根模块会迅速演变成一个高危的“巨石文件”:

Day 1:   引入 ConfigModule 读取配置
Day 7:   引入 LoggerModule (Pino/Winston) 替换默认日志,带上一长串 Transport
Day 15:  引入 PrismaModule / TypeOrmModule.forRootAsync() 连接数据库
Day 30:  引入 Redis / BullModule 连接队列
Day 60:  注册 APP_GUARD, APP_INTERCEPTOR, APP_PIPE, APP_FILTER 增强器
Day 120: 加入 20+ 个业务模块 (User, Order, Payment, Product...)

最终的 AppModule 会带来三大工程隐患:

// 典型失控的 app.module.ts
@Module({
  imports: [
    // 基础设施 1:环境配置 + 校验
    ConfigModule.forRoot({ isGlobal: true, validate: validateEnv }),
    // 基础设施 2:日志异步工厂
    LoggerModule.forRootAsync({ useFactory: (cfg: ConfigService) => ({ ... }) }),
    // 基础设施 3:持久层与缓存
    PrismaModule,
    RedisModule.forRoot({ ... }),
    ScheduleModule.forRoot(),
    // 基础设施 4:跨切面鉴权基础
    JwtModule.registerAsync({ ... }),

    // 业务模块(被淹没在配置细节的汪洋大海中)
    UserModule,
    OrderModule,
    PaymentModule,
    InventoryModule,
    NotificationModule,
    // ... 更多业务模块
  ],
  providers: [
    // 全局增强器与一堆未解耦的 Provider
    { provide: APP_GUARD, useClass: JwtAuthGuard },
    { provide: APP_INTERCEPTOR, useClass: ResponseTransformInterceptor },
    { provide: APP_PIPE, useValue: new ValidationPipe({ transform: true, whitelist: true }) },
    { provide: APP_FILTER, useClass: GlobalExceptionsFilter },
  ],
})
export class AppModule {}
  1. 认知负载极高:想知道系统“包含哪些业务能力”,必须在几十行复杂的异步配置(useFactory、环境变量分支逻辑)中翻找。
  2. 高频冲突与评审噪音:基础设施工程师(调日志级别、改数据库连接池)和业务工程师(增删业务模块)同时修改 app.module.ts,造成频繁的 Git 冲突和混杂的 Code Review 记录。
  3. “全局单例”的脆弱性ConfigModule.forRoot({ isGlobal: true })ScheduleModule.forRoot() 这类“只能初始化一次”的模块,由于缺乏物理隔离,新人极易在其他子模块中重复 imports: [ConfigModule.forRoot()] 导致不可预期的状态重置。

此处内容已隐藏回复后方可阅读。

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。