'Can you import a NestJS module on condition

I'am creating a microservice in NestJS. Now I want to use RabbitMQ to send messages to another service.

My question is: is it possible to import the RabbitmqModule based on a .env variable? Such as: USE_BROKER=false. If this variable is false, than don't import the module?

RabbitMQ is imported in the GraphQLModule below.

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      autoSchemaFile: true,
      context: ({ req }) => ({ req }),
    }),
    DatabaseModule,
    AuthModule,
    RabbitmqModule,
  ],
  providers: [UserResolver, FamilyResolver, AuthResolver],
})
export class GraphQLModule {}

RabbitmqModule:

import { Global, Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq';
import { UserProducer } from './producers/user.producer';

@Global()
@Module({
  imports: [
    RabbitMQModule.forRootAsync(RabbitMQModule, {
      useFactory: async (config: ConfigService) => ({
        exchanges: [
          {
            name: config.get('rabbitMQ.exchange'),
            type: config.get('rabbitMQ.exchangeType'),
          },
        ],
        uri: config.get('rabbitMQ.url'),
        connectionInitOptions: { wait: false },
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [UserProducer],
  exports: [UserProducer],
})
export class RabbitmqModule {}


Solution 1:[1]

I think the recommended way to do so is to use the DynamicModule feature from NestJS.

It is explained here: https://docs.nestjs.com/fundamentals/dynamic-modules

Simply check your environment variable in the register function and return your Module object. Something like:

@Module({})
export class GraphQLModule {
  static register(): DynamicModule {
    const imports = [
      GraphQLFederationModule.forRoot({
        autoSchemaFile: true,
        context: ({ req }) => ({ req }),
      }),
      DatabaseModule,
      AuthModule]
    if (process.env.USE_BROKER) {
      modules.push(RabbitmqModule)
    }
    return {
      imports,
      providers: [UserResolver, FamilyResolver, AuthResolver],
    };
  }
}

Solution 2:[2]

Well I tried a simple workaround, in a small nest project, and it worked just fine. Check it out:

const mymodules = [TypeOrmModule.forRoot(typeOrmConfig), UsersModule];
if (config.get('importModule')) {
    mymodules.push(PoopModule);
}
@Module({
    imports: mymodules,
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

I created an "importModule" in my env/config, and tested it with true and false. If true my Poop module gets deployed, else it doesn't deploy, only the other modules.

Can you try the same in your project?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MysteriousPerson
Solution 2 GabLeRoux