Как ввести конфигурацию пути в ServeStaticModule из другой службы?

В документации NestJS говорится о статических файлах сервера, например:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Но как практик DI и SOLID я хочу сделать rootPath настраиваемым. Допустим, у меня есть ConfigModule или мой собственный ConstantsModule. Как мне вводитьrootPath подобным образом?

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: this.configService.get<string>('staticRootPath'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

4 ответа

Правильный ответ:

      ServeStaticModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => [{
          rootPath: join(__dirname, '..', configService.get<string>('STATIC_FOLDER')),
      }]
})

Даже если это не задокументировано, вы можете использовать forRootAsync, для модулей NestJS типично иметь эту версию, которая позволяет вам вводить зависимости и / или выполнять асинхронную конфигурацию:

@Module({
  imports: [
    ServeStaticModule.forRootAsync({
      imports: [ConfigModule],
      injects: [ConfigService],
      useFactory: (configService) => ({
        rootPath: configService.get<string>('staticRootPath')
      })
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Для справки нашел в исходниках GitHub

Я решил это, внедрив ServeStaticModuleOptionsFactory.

служить-статической-configuration.module.ts

      import { Module } from '@nestjs/common';
import { ConfigurationModule } from '../configuration/configuration.module';
import { ConfigurationService } from '../configuration/configuration.service';
import { ServeStaticConfigurationService } from './serve-static-configuration.service';

@Module({
    imports: [ConfigurationModule],
    providers: [ServeStaticConfigurationService, ConfigurationService],
    exports: [ServeStaticConfigurationService]
})
export class ServeStaticConfigurationModule { }

служить-статической-configuration.service.ts

      import { Injectable } from '@nestjs/common';
import { ServeStaticModuleOptions, ServeStaticModuleOptionsFactory } from '@nestjs/serve-static';
import { ConfigurationService } from '../configuration/configuration.service';

@Injectable()
export class ServeStaticConfigurationService implements ServeStaticModuleOptionsFactory {
    constructor(private configurationService: ConfigurationService) { }

    createLoggerOptions(): ServeStaticModuleOptions[] | Promise<ServeStaticModuleOptions[]> {
        return [{
            rootPath: this.configurationService.wwwRoot,
            exclude: [`/api*`]
        }];
    }
}

app.module.ts

      import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { AppController } from './app.controller';
import { ServeStaticConfigurationModule } from './serve-static-configuration/serve-static-configuration.module';
import { ServeStaticConfigurationService } from './serve-static-configuration/serve-static-configuration.service';

@Module({
    imports: [
        ServeStaticModule.forRootAsync({
            imports: [ServeStaticConfigurationModule],
            useExisting: ServeStaticConfigurationService
        })
    ],
    controllers: [AppController]
})
export class AppModule { }

Это должен быть массив, как указано в коде:

      useFactory?: (...args: any[])
Другие вопросы по тегам