Why is .env undefined?

Viewed 110

app.module.ts

@Module({
    imports: [
        ConfigModule.forRoot({
            isGlobal: true
        }),
        MongooseModule.forRoot(process.env.MONGO_DB_URI, {useFindAndModify: false}),
        UsersModule,
        RolesModule,
        AuthenticationModule,
        TwoFactorAuthModule,
        RememberPasswordModule,
        RegistrationLinkModule
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

authentication.module.ts

@Module({
    imports: [
        JwtModule.register({
            secret: process.env.JWT_SECRET
        }),
        UsersModule,
        TwoFactorAuthModule,
        RememberPasswordModule,
        RegistrationLinkModule
    ],
    controllers: [AuthenticationController],
    providers: [AuthenticationService]
})
export class AuthenticationModule {}

In AuthenticationModule process.env is undefined. But if I use it in AuthenticationService it works fine. How can I use process.env in module file?

2 Answers

As Francois said, you can make the config() method the first thing in your main.ts file. Keep in mind this must be done before you import any file that has a decorator using process.env.

Another option would be to use a package like @golevelup/profiguration, which is similar to dotenv and can be used inside of decorators.

The last option, that Istiyak Tailor references is using the @nestjs/config package and the ConfigModule and ConfigService. For this, you should make use of the asynchronous registration methods, such as registerAsync and forRootAsync. Then you can use a configuration like

JwtModule.registerAsync({
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    secret: config.get('JWT_SECRET'),
  })
})

(similar for the MongooseModule but using forRootAsync instead of registerAsync)

This tells Nest to wait for the ConfigModule to finish instantiating and the use the ConfigService inside of the instantiation for the JwtModule and MognooseModule.

You could also use a configuration class instead of useFactory, but they essentially are the same thing.

You should try to import dotenv and configure it at the beginning of your main.ts file before you bootstrap your application.

import * as dotenv from 'dotenv'
dotenv.config()

async function bootstrap() { ... }

As stated in dotenv doc: "As early as possible in your application, require and configure dotenv."

Related