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

我不明白为什么我的env-var不能在我的应用程序中随处可用。

如果我不得不猜测,那么您调用dotenvconfig()方法太晚了。在Typescript中,decorator是在模块导入时运行的,所以@Module()中的任何东西几乎都会立即运行。但是,类方法的函数调用中的任何内容在调用该函数之前都不会运行。我建议,在您的main.ts文件中,将这些作为前两行:

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

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

在使用Nest提供的ConfigModule时,另一种选择是使用异步注册过程,使用工厂或类来提供正确的配置。在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'),
})
})

JwtModule访问env变量时,您可以使用registerSync,您的代码应该是这样的:

JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
secret: config.get('JWT_SECRET_KEY'),
signOptions: { expiresIn: '1h' },
}),
})

最新更新