0

我正在尝试在“config.ts”中的一个文件中设置我的所有配置,将其加载到 ConfigService,然后使用配置接口从中获取值。所以这是我的 config.ts,它具有来自我的 .env 文件和静态变量的 ENV 变量。

UPD:用这个例子做回购

import { Config } from './config.interface';

const config: Config = {
  typeorm: {
    type: 'postgres',
    host: process.env.DB_HOST,
    port: +process.env.DB_PORT,
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    synchronize: process.env.NODE_ENV !== 'prod',
    logging: true,
    entities: [User, RefreshToken],
  },
};

export default () => config;

这是我的界面:

export interface Config {
  typeorm: TypeOrmConfig;
}

export interface TypeOrmConfig {
  type: string;
  host: string;
  port: number;
  username: string;
  password: string;
  database: string;
  synchronize: boolean;
  logging: boolean;
  entities: any[];
}

配置加载到 app.module.ts 中的 ConfigModule

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: '.dev.env',
      load: [config],
    }),
}),

例如,我想使用此设置设置我的 TypeOrmModule。基于 NestJs 文档

TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => {
        const config = configService.get<TypeOrmConfig>('typeorm');
        console.log(config);
        return {
          type: config.type,
          host: config.host,
          port: +config.port,
          username: config.username,
          password: config.password,
          database: config.database,
          synchronize: config.synchronize,
          logging: config.logging,
          entities: config.entities,
        };
      },
      inject: [ConfigService],
    }),

这是问题所在。配置中的静态值是可以的,但我所有的 ENV 变量都是未定义的。这是 console.log 输出:

{
  type: 'postgres',
  host: undefined,
  port: NaN,
  username: undefined,
  password: undefined,
  database: undefined,
  synchronize: true,
  logging: true,
  entities: [
    [class User extends CoreEntity],
    [class RefreshToken extends CoreEntity]
  ]
}

我不明白未定义的 ENV var 有什么问题我将不胜感激任何解释和帮助

4

1 回答 1

3

简而言之,NestJS 要求您为您尝试在此处访问的自定义配置“typeorm”定义一个命名空间(请参阅配置命名空间):

const config = configService.get<TypeOrmConfig>('typeorm');

这意味着您必须使用registerAs函数来创建命名空间:

import { registerAs } from '@nestjs/config';
import { TypeOrmConfig } from './config.interface';

export default registerAs(
  'typeorm',
  (): TypeOrmConfig => ({
    type: 'postgres',
    host: process.env.DB_HOST,
    port: +process.env.DB_PORT,
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    synchronize: process.env.NODE_ENV !== 'prod',
    logging: true,
    entities: [],
  }),
);

这会成功的。但是,我们可以对此进行改进。

除了为 TypeORM 配置定义您自己的接口之外,您还可以使用和/或扩展现有接口来减少样板代码(下面我会提到ConnectionOptions,尽管TypeOrmModuleOptions根据您的配置需要可能更合适)。我还建议为环境变量提供后备值:

import { registerAs } from '@nestjs/config';
import { ConnectionOptions } from 'typeorm';

const CONNECTION_TYPE = 'postgres';

export default registerAs(
  'typeorm',
  (): ConnectionOptions => ({
    type: CONNECTION_TYPE,
    host: process.env.DB_HOST || 'default_value',
    port: +process.env.DB_PORT || 3000,
    username: process.env.DB_USERNAME || 'default_value',
    password: process.env.DB_PASSWORD || 'default_value',
    database: process.env.DB_NAME || 'default_value',
    synchronize: process.env.NODE_ENV !== 'prod',
    logging: true,
    entities: [],
  }),
);  

此外,无需再次为 TypeOrmModule 显式分配配置值,您可以简单地:

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) =>
    await configService.get('typeorm'),
  inject: [ConfigService],
}),

作为个人风格,我喜欢创建配置枚举以包含配置名称以防止拼写错误。考虑一下:

export enum ConfigEnum {
  TYPEORM = 'typeorm',
}

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) =>
    await configService.get<Promise<TypeOrmModuleOptions>>(
      ConfigEnum.TYPEORM,
    ),
  inject: [ConfigService],
})

Async / Await 模式在这里也是多余的,因为我们实际上并没有执行任何异步操作,所以这也可以:

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) =>
    configService.get<TypeOrmModuleOptions>(ConfigEnum.TYPEORM),
  inject: [ConfigService],
})

欢迎来到 StackOverflow!

附言。我已提出拉取请求,请参阅https://github.com/JustDenP/nest-config/pull/1

于 2021-04-20T15:28:42.990 回答