Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJs: Unable to read env variables in module files but able in service files?

I have an .env file at the root of my NestJs project with some env variables in it.

The strange thing is that I am able to read the variables in service files but not in module files.

So in a service file like users.service.ts, this works:

saveAvatar() {
    const path = process.env.AVATAR_PATH    // returns value from .env
}

However, when accessing a path in a module file like auth.module.ts, this returns an empty value:

@Module({
    imports: [
       JwtModule.register({
          secretOrPrivateKey: process.env.SECRET   // process.env.SECRET returns an empty string
       })
    ]
})

Why is that so? How can I reliably access environmental variables in the .env file in NestJs?

like image 736
Carven Avatar asked Apr 14 '19 08:04

Carven


2 Answers

Your .env file is not yet read in when your JwtModule is instantiated. So either read it in earlier e.g. in your main.ts before the nest app is created or better: create a ConfigService and make the dependency on your config explicit:

JwtModule.registerAsync({
    imports: [ConfigModule],
    useFactory: async (configService: ConfigService) => ({
      secret: configService.jwtSecret,
    }),
    inject: [ConfigService],
}),

See this answer on how to create a ConfigService.

like image 61
Kim Kern Avatar answered Sep 28 '22 08:09

Kim Kern


The declaring order is important in your use case.

This works:

@Module({
  imports: [
    ConfigModule.forRoot(),
    ScheduleModule.forRoot(),
    TypeOrmModule.forRoot({
      type: 'mongodb',
      host: process.env.SYN_MONGO_HOST,
      port: +process.env.SYN_MONGO_PORT,
      username: process.env.SYN_MONGO_USERNAME,
      password: process.env.SYN_MONGO_PASSWORD,
      database: process.env.SYN_MONGO_DATABASE,
      authSource: 'admin',
      autoLoadEntities: true,
    }),
  ],
  controllers: [],
  providers: [],
})
export class ConfigurationModule {}

When this doesn't

@Module({
  imports: [
    ScheduleModule.forRoot(),
    TypeOrmModule.forRoot({
      type: 'mongodb',
      host: process.env.SYN_MONGO_HOST,
      port: +process.env.SYN_MONGO_PORT,
      username: process.env.SYN_MONGO_USERNAME,
      password: process.env.SYN_MONGO_PASSWORD,
      database: process.env.SYN_MONGO_DATABASE,
      authSource: 'admin',
      autoLoadEntities: true,
    }),
    ConfigModule.forRoot(),
  ],
  controllers: [],
  providers: [],
})
export class ConfigurationModule {}

This is because ConfigModule is load before or after TypeOrmModule.

like image 30
hugo blanc Avatar answered Sep 28 '22 10:09

hugo blanc