Global Modules
⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 10 min
Global modules provide a set of providers that are available everywhere in the application without having to explicitly import the module.
Overview
If you have to import the same module (e.g., DatabaseModule, ConfigModule) everywhere, it can lead to a lot of boilerplate code in your imports arrays.
To solve this, NestJS provides the @Global() decorator. When a module is marked as global, the providers it exports become available to every other module in the application automatically.
Key Concepts
@Global()Decorator: Placed above the@Module()decorator.- Registration: A global module should be registered only once, typically in the root
AppModuleor a dedicatedCoreModule. - Automatic Availability: Providers exported by a global module can be injected anywhere without needing to import the global module in the consuming feature module.
Code Examples
Defining a Global Module
import { Module, Global } from '@nestjs/common';
import { ConfigService } from './config.service';
// Mark the module as global
@Global()
@Module({
providers: [ConfigService],
// You still must export the providers you want to make globally available
exports: [ConfigService],
})
export class ConfigModule {}
Registering the Global Module
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from './config/config.module';
import { UsersModule } from './users/users.module';
@Module({
// Register it once here
imports: [ConfigModule, UsersModule],
})
export class AppModule {}
Consuming the Global Provider
// users.module.ts
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
@Module({
// Notice we DO NOT import ConfigModule here
providers: [UsersService],
})
export class UsersModule {}
// users.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '../config/config.service';
@Injectable()
export class UsersService {
// We can just inject it, and it works!
constructor(private configService: ConfigService) {}
}
Best Practices
- Use Sparingly: Making everything global is a bad design decision. It obscures dependencies and makes unit testing significantly harder because you have to guess which global providers a class secretly relies on.
- Good Candidates for Global: Configuration (
ConfigModule), Database Connections (TypeOrmModule.forRoot()), and global logging services. - CoreModule Pattern: A common pattern is to create a single global
CoreModulethat bundles and exports all global infrastructure (DB, Config, Logger) and import thatCoreModuleexactly once inAppModule.