Nestjs项目App Module无法读取env文件变量但main.ts可正常访问
问题原因
- 你写在
@Module装饰器外的console.log(process.env.DB_URI)会在AppModule文件被Node导入时立即执行,此时ConfigModule.forRoot()还没运行,.env文件内容未被加载到process.env上,所以输出undefined。 - 你当前使用的
MongooseModule.forRoot()是同步注册方法,执行时机早于ConfigModule的初始化完成时机,自然也读不到刚加载的env变量。 - main.ts能正常读取的原因大概率是你在main.ts入口顶部提前手动引入了dotenv加载.env,或者你是在Nest应用实例初始化完成后才打印的env变量,此时ConfigModule已经加载完毕。如果你的dotenv引入写在AppModule导入语句之后,也会出现AppModule顶层代码读不到env的问题。
修复方案
推荐使用Nest官方推荐的异步注册方式,依赖ConfigService获取环境变量,避免加载时机问题,修改后的AppModule代码如下:
import { ConfigModule, ConfigService } from '@nestjs/config'; import { MongooseModule } from '@nestjs/mongoose'; import { OnModuleInit } from '@nestjs/common'; @Module({ imports: [ ConfigModule.forRoot({ envFilePath: ['.env'], isGlobal: true, cache: true, }), UsersModule, FoodItemsModule, MacroCalculatorModule, // 替换同步注册为异步注册 MongooseModule.forRootAsync({ useFactory: (configService: ConfigService) => ({ uri: configService.get<string>('DB_URI'), // 其他mongoose配置项可以在这里补充 }), inject: [ConfigService], }), ], controllers: [AppController], providers: [AppService], }) export class AppModule implements OnModuleInit { constructor(private configService: ConfigService) {} // 模块初始化完成后打印验证变量 onModuleInit() { console.log(this.configService.get<string>('DB_URI')); // 可正常获取到值 } }
如果你希望直接通过process.env全局读取env变量,可以在项目入口文件main.ts的最顶部添加import 'dotenv/config',保证该语句在所有其他导入语句之前执行,即可让所有模块顶层代码都能读取到env变量,不过更推荐统一使用ConfigService来管理环境变量,类型更安全也更符合Nest的开发规范。
内容的提问来源于stack exchange,提问作者Sachin Yadav
相关产品推荐
相关产品推荐

