NestJS模块(Module) #

什么是模块? #

模块是NestJS中组织应用结构的基本单元。每个NestJS应用至少有一个模块——根模块(通常是AppModule)。模块使用@Module()装饰器来定义,它提供了NestJS用来组织应用结构的元数据。

@Module装饰器 #

@Module()装饰器接收一个对象,包含以下属性:

typescript
@Module({
  imports: [],      // 导入其他模块
  controllers: [],  // 注册控制器
  providers: [],    // 注册提供者
  exports: [],      // 导出提供者
})
export class AppModule {}
属性 说明
imports 导入其他模块,可以使用其导出的提供者
controllers 注册此模块中的控制器
providers 注册此模块中的提供者(服务)
exports 导出提供者,供其他模块使用

模块的基本使用 #

创建模块 #

使用CLI创建模块:

bash
nest g module users

生成的代码:

typescript
import { Module } from '@nestjs/common';

@Module({})
export class UsersModule {}

完整的模块示例 #

typescript
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

模块导入与导出 #

导出提供者 #

当其他模块需要使用当前模块的服务时,需要导出:

typescript
@Module({
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],  // 导出UsersService
})
export class UsersModule {}

导入模块 #

在另一个模块中导入并使用:

typescript
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { AuthService } from './auth.service';

@Module({
  imports: [UsersModule],  // 导入UsersModule
  providers: [AuthService],
})
export class AuthModule {
  constructor(private usersService: UsersService) {
    // 可以使用UsersService
  }
}

模块导出示意图 #

text
┌─────────────────────────────────────────────────────────────┐
│                      UsersModule                             │
├─────────────────────────────────────────────────────────────┤
│  providers: [UsersService, UsersRepository]                 │
│  controllers: [UsersController]                              │
│  exports: [UsersService]  ←────────────────────────┐        │
└─────────────────────────────────────────────────────│───────┘
                                                      │
                                                      │ 可访问
                                                      ↓
┌─────────────────────────────────────────────────────────────┐
│                      AuthModule                              │
├─────────────────────────────────────────────────────────────┤
│  imports: [UsersModule]                                      │
│  providers: [AuthService]  ← 可以注入 UsersService           │
│  controllers: [AuthController]                               │
└─────────────────────────────────────────────────────────────┘

模块重导出 #

模块可以重导出导入的模块:

typescript
@Module({
  imports: [CommonModule, UsersModule],
  exports: [CommonModule, UsersModule],  // 重导出
})
export class SharedModule {}

其他模块只需导入SharedModule,就能使用CommonModuleUsersModule导出的提供者。

全局模块 #

使用@Global()装饰器创建全局模块:

typescript
import { Module, Global } from '@nestjs/common';
import { ConfigService } from './config.service';

@Global()
@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule {}

全局模块的提供者在所有模块中可用,无需重复导入。

注意: 过度使用全局模块会导致代码难以维护,建议谨慎使用。

动态模块 #

动态模块允许在运行时配置模块:

基本结构 #

typescript
import { Module, DynamicModule } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options: ConfigOptions): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}

使用动态模块 #

typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [
    ConfigModule.register({
      isGlobal: true,
      folder: './config',
    }),
  ],
})
export class AppModule {}

动态模块示例:数据库模块 #

typescript
import { Module, DynamicModule } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({})
export class DatabaseModule {
  static forRoot(options: DatabaseOptions): DynamicModule {
    return {
      module: DatabaseModule,
      imports: [
        TypeOrmModule.forRoot({
          type: options.type,
          host: options.host,
          port: options.port,
          username: options.username,
          password: options.password,
          database: options.database,
          entities: options.entities,
          synchronize: options.synchronize,
        }),
      ],
      providers: [],
      exports: [TypeOrmModule],
    };
  }
}

模块懒加载 #

NestJS支持模块懒加载,可以按需加载模块:

typescript
import { Module } from '@nestjs/common';
import { LazyModuleLoader } from '@nestjs/core';

@Module({
  imports: [],
})
export class AppModule {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}

  async onModuleInit() {
    const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
    const service = moduleRef.get(LazyService);
  }
}

模块生命周期钩子 #

模块可以实现以下生命周期钩子:

钩子 说明
onModuleInit() 模块初始化完成时调用
onModuleDestroy() 模块销毁时调用
onApplicationBootstrap() 应用启动完成时调用
onApplicationShutdown() 应用关闭时调用
typescript
import { Module, OnModuleInit, OnModuleDestroy } from '@nestjs/common';

@Module({})
export class UsersModule implements OnModuleInit, OnModuleDestroy {
  onModuleInit() {
    console.log('UsersModule initialized');
  }

  onModuleDestroy() {
    console.log('UsersModule destroyed');
  }
}

模块组织最佳实践 #

1. 按功能划分模块 #

text
src/
├── modules/
│   ├── users/           # 用户模块
│   ├── auth/            # 认证模块
│   ├── products/        # 产品模块
│   └── orders/          # 订单模块
└── common/              # 公共模块
    ├── database/
    ├── logger/
    └── config/

2. 共享模块 #

创建共享模块,导出常用的提供者:

typescript
@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class SharedModule {}

3. 核心模块 #

创建核心模块,包含应用级别的提供者:

typescript
@Global()
@Module({
  imports: [],
  providers: [ConfigService, LoggerService],
  exports: [ConfigService, LoggerService],
})
export class CoreModule {}

4. 功能模块结构 #

text
users/
├── dto/                    # 数据传输对象
│   ├── create-user.dto.ts
│   └── update-user.dto.ts
├── entities/               # 实体
│   └── user.entity.ts
├── interfaces/             # 接口
│   └── user.interface.ts
├── users.controller.ts     # 控制器
├── users.module.ts         # 模块
├── users.service.ts        # 服务
└── users.repository.ts     # 仓库

循环依赖处理 #

当两个模块相互依赖时,会产生循环依赖问题。

使用forwardRef解决 #

typescript
// users.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { AuthModule } from '../auth/auth.module';

@Module({
  imports: [forwardRef(() => AuthModule)],
  exports: [UsersService],
})
export class UsersModule {}

// auth.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [forwardRef(() => UsersModule)],
  exports: [AuthService],
})
export class AuthModule {}

在服务中使用forwardRef #

typescript
@Injectable()
export class UsersService {
  constructor(
    @Inject(forwardRef(() => AuthService))
    private authService: AuthService,
  ) {}
}

模块配置示例 #

完整的用户模块 #

typescript
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { UsersRepository } from './users.repository';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersService, UsersRepository],
  exports: [UsersService],
})
export class UsersModule {}

总结 #

本章深入学习了NestJS模块系统:

  • @Module()装饰器的使用
  • 模块的导入和导出
  • 全局模块和动态模块
  • 模块生命周期钩子
  • 循环依赖的处理

接下来,让我们学习 控制器(Controller)

最后更新:2026-03-28