Как ввести конфигурацию пути в 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[])