为什么 .env 未定义?

Why is .env undefined?

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 {}

在 AuthenticationModule 中 process.env 未定义。但是,如果我在 AuthenticationService 中使用它,它就可以正常工作。如何在模块文件中使用 process.env?

在 bootstrap 您的应用程序之前,您应该尝试导入 dotenv 并在 main.ts 文件的开头配置它。

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

async function bootstrap() { ... }

dotenv 文档所述:“在您的应用程序中尽早要求并配置 dotenv。”

正如 Francois 所说,您 可以 使 config() 方法成为 main.ts 文件中的第一件事。请记住,必须 在导入 任何 具有使用 process.env.

装饰器的文件之前完成

另一种选择是使用像 @golevelup/profiguration 这样的包,它类似于 dotenv 并且可以在装饰器内部使用。

Istiyak Tailor 引用的最后一个选项是使用 @nestjs/config 包以及 ConfigModuleConfigService。为此,您应该使用异步注册方法,例如 registerAsyncforRootAsync。然后你可以使用像

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

(与 MongooseModule 类似,但使用 forRootAsync 而不是 registerAsync

这告诉 Nest 等待 ConfigModule 完成实例化,并在 JwtModuleMognooseModule.[=30 的实例化中使用 ConfigService =]

你也可以 use a configuration class 而不是 useFactory,但它们本质上是一样的。