Импортируйте внутренние модули условно на основе асинхронной конфигурации в NestJS

#node.js #typescript #nestjs #nestjs-config

Вопрос:

Я столкнулся с проблемой NestJS динамической загрузки модуля. У меня есть родительский динамический модуль, который получает асинхронные конфигурации useFactory . Он также импортирует несколько дочерних модулей внутри. useFactory Метод возвращает фактическую конфигурацию, сообщающую нам, какие дочерние модули должны быть загружены, но почему-то я не могу этого сделать. Как я могу загрузить внутренние модули на основе асинхронной конфигурации родительских модулей? Вот пример:

parent.options.ts

 import { ModuleMetadata } from '@nestjs/common/interfaces';

interface ActualConfigForChildren {
    child1?: {
        child1Id: string;
    };
    child2?: {
        child2Id: string;
    };
    child3?: {
        child3Id: string;
    };
}

export interface ParentModuleAsyncOptions
  extends Pick<ModuleMetadata, 'imports'> {
  name?: string;
  useFactory?: (
    ...args: any[]
  ) => Promise<ActualConfigForChildren> | ActualConfigForChildren;
  inject?: any[];
}
 

родительский.модуль.ts

 import { Module, Global, DynamicModule } from '@nestjs/common';
import { ParentModuleAsyncOptions } from './parent.options';

@Global()
@Module({})
export class ParentModule {

  static forRootAsync(options: ParentModuleAsyncOptions): DynamicModule {
    return {
      module: ParentModule,
      providers: [{
        provide: 'PARENT_MODULE_CONFIG_SERVICE',
        useFactory: options.useFactory,
        inject: options.inject || [],
      }],
      exports: ['PARENT_MODULE_CONFIG_SERVICE'],
      imports: [
        ChildModule1, // I want to import it if child1 config is present
        ChildModule2, // I want to import it if child2 config is present
        ChildModule3, // similarly
      ],
    };
  }
}
 

app.module.ts (где я фактически импортирую свой родительский модуль)

 @Module({
    imports: [
      ParentModule.forRootAsync({
        useFactory: (/* Assume I'll make use of ConfigService here */) => ({
            child1: {
                child1Id: '123'
            },
            child2: {
                child2Id: '123'
            },
            child3: {
                child3Id: '123'
            }
        })
      }),
    ],
  })
export class AppModule {}
 

Although the child modules can access PARENT_MODULE_CONFIG_SERVICE but I don’t want them to load at all.