Переменные Env в Nest JS не видны в каждом модуле? - PullRequest
1 голос
/ 24 апреля 2020

Я сохраняю свою конфигурацию в файле .env при разработке приложения.

Это мои app.module.ts:

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRoot({
      autoLoadEntities: true,
      database: process.env.TYPEORM_DATABASE,
      host: process.env.TYPEORM_HOST,
      password: process.env.TYPEORM_PASSWORD,
      port: (process.env.TYPEORM_PORT as unknown) as number,
      type: 'postgres',
      username: process.env.TYPEORM_USERNAME,
    }),
    AuthModule,
    (...)
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

И typeorm используют правильные значения из process.env.TYPEORM_... переменные.

Это мой auth.module.ts:

@Module({
  providers: [JwtStrategy, (...)],
  imports: [
    JwtModule.register({
      secret: process.env.JWT_SECRET,
      (...)
    }),
    (...)
  ],
  controllers: [AuthController],
})
export class AuthModule {}

И я получаю сообщение об ошибке из JwtModule, что secret не может быть пустым. Конечно, JWT_SECRET устанавливается в .env файле.

Это мой jwt.strategy.ts:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      secretOrKey: process.env.JWT_SECRET,
      (...)
    });
  }
  (...)
}

И здесь process.env.JWT_SECRET загружен правильно.

Я не могу понять, почему мои env-переменные не доступны везде в моем приложении.

1 Ответ

2 голосов
/ 24 апреля 2020

Если бы мне пришлось угадать, вы слишком поздно вызываете метод dotenv config(). В Typescript декораторы запускаются при импорте модулей, поэтому все, что в @Module(), запускается практически сразу. Однако все, что находится в вызове функции метода класса, не будет запущено, пока эта функция не будет вызвана. Я бы посоветовал в вашем файле main.ts иметь эти первые две строки:

import { config } from 'dotenv';
config();

Таким образом, любой файл .env читается и добавляется в process.env, прежде чем что-либо еще получит шанс выполнения.

Другой вариант, так как вы используете ConfigModule, предоставленный Nest , - это использовать асинхронный процесс регистрации, где вы используете либо фабрику, либо класс вместо предоставить правильные конфигурации. В вашей конфигурации TypeOrm процесс регистрации asyn c может выглядеть следующим образом:

TypeOrmModule.forRootAsync({
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    autoLoadEntities: true,
    database: config.get<string>('TYPEORM_DATABASE'),
    host: config.get<string>('TYPEORM_HOST'),
    password: config.get<string>('TYPEORM_PASSWORD'),
    port: config.get<number>('TYPEORM_PORT'),
    type: 'postgres',
    username: config.get<string>('TYPEORM_USERNAME'),
  })
})
...