首页 > 解决方案 > NestJS 中的环境变量在每个模块中都不可见?

问题描述

.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已正确加载。

我不明白为什么我的环境变量在我的应用程序中无处不在。

标签: nestjs

解决方案


如果我不得不猜测,那么您调用dotenv'config()方法为时已晚。在 Typescript 中,装饰器在模块导入时运行,因此其中的任何内容@Module()几乎都会立即运行。但是,在调用该函数之前,不会运行类方法的函数调用中的任何内容。我建议,在您的main.ts文件中,将这些作为前两行:

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

这样,任何.env文件都被读取并添加到其他文件process.env有机会运行之前。

当您使用ConfigModuleNest 提供的时,另一个选项是使用异步注册过程,您可以使用工厂或类来提供正确的配置。在您的 TypeOrm 配置中,异步注册过程可能如下所示:

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'),
  })
})

推荐阅读