typescript - Ako nastaviť súbory prostredia s konfiguráciou podobnou Angularu v NestJS?


Umožňuje NestJS mať súbory prostredia podobným spôsobom, ako to má Angular?

V Angulari máte samostatné súbory prostredia, ktoré sa automaticky mapujú v závislosti od prostredia aplikácie (vývoj, produkcia, ...):

  • src/prostredia/prostredie.ts
  • src/environments/environment.prod.ts

Poskytuje @nestjs/config podobnú elegantnú a jednoduchú metódu na oddelenie a správu premenných prostredia? Bohužiaľ, nemôžem nájsť podrobný vysvetlenie ani použiteľný príklad tohto vzoru pre NestJS v oficiálnej dokumentácii: https://docs.nestjs.com/techniques/configuration

Odpoveď č. 1

Nepoznám Angular, takže neviem, či je tak intuitívny, ale mali by ste sa pozrieť na použitie Dynamických modulov na vloženie vašej konfigurácie.

Príklady v dokumentácii NestJS už sú dosť blízko tomu, čo chcete, okrem toho, že pracujú s rôznymi súbormi .env, ktoré sú načítané priamo v ConfigService.

Pre váš prípad je potrebné nejaké programovanie, ale budete to musieť urobiť iba raz a potom to môžete znovu použiť v ľubovoľnom inom projekte NestJS. Ak sa pozriete do dokumentácie, môžete odvodiť poskytovateľa Injectable(), ktorý je poskytovaný pomocou ConfigModule.register() a ktorý je na základe process.env.NODE_ENV inštanciou príslušnej triedy prostredia.

Alebo môžete samozrejme použiť predpripravený príklad, ktorý priamo načítava .env. Ale potom to nie je silne typované.


Osobne používam overovanie schém založené na Joi a menné priestory konfigurácie a tiež definujem rozhranie pre nastavenia konfigurácie. Napríklad ako v tomto ukážkovom kóde:

env.schema.ts:

export const envSchema = Joi.object({

  NODE_ENV: Joi.string()
    .valid('development', 'production')
    .default('development'),

  EMAIL_VERIFICATION_SECRET: Joi.string().when('NODE_ENV', {
    is: 'production',
    then: Joi.required(),
    otherwise: Joi.optional().default('the_email_verification_secret'),
  }),
});

email.config.ts:

interface EmailConfig {
  verificationSecret: string;
}

export default registerAs('email', (): EmailConfig => ({
  verificationSecret: process.env.EMAIL_VERIFICATION_SECRET,
}));

notification.module.ts:

@Module({
  imports: [
    ConfigModule.forFeature(emailConfig),
  ],
})
export class NotificationModule {}

email-notification.service.ts:

@Injectable()
export class EmailNotificationService {
  private secret: string;

  constructor(
    @Inject(emailConfig.KEY)
    private mailConfig: ConfigType<typeof emailConfig>,
  ) {
    this.secret = this.mailConfig.verificationSecret;
  }
}

Samozrejme, nemusíte používať konfiguračné menné priestory, ale rozdeľuje to konfiguráciu do presne tých častí, ktoré potrebujete v konkrétnom module. Existuje silné typovanie prostredníctvom rozhrania a pomocou Joi je vaša schéma zároveň overená a prispôsobená vhodnému prostrediu.