繁体   English   中英

NestJS - 如何在主应用程序模块文件中使用 .env 变量进行数据库连接

[英]NestJS - How to use .env variables in main app module file for database connection

我正在开发我的第一个 NestJS 应用程序,该应用程序在app.module.ts中使用硬编码的数据库连接字符串运行良好。

但是根据我们的要求,我不得不从环境文件中选择数据库配置值。 为此,我遵循了nestjs文档网站上的配置文档 - https://docs.nestjs.com/techniques/configuration

但问题是我需要在同一个文件中使用 .env 变量进行数据库连接,这是失败的。

这是我工作正常的原始代码:

@Module({
  imports: [
    MongooseModule.forRoot(`mongodb+srv://myusername:mypassword@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' }),
    ProductModule,
    CategoryModule,
  ],
  controllers: [
    AppController,
    HealthCheckController,
  ],
  providers: [AppService, CustomLogger],
})

现在,我想根据环境从 .env 文件中选择那些 DB 值,例如local.envdev.env等。 现在,我的这段代码不起作用:

@Module({
  imports: [
    ConfigModule.forRoot({ envFilePath: `${process.env.NODE_ENV}.env` }),
    MongooseModule.forRoot(`mongodb+srv://${ConfigModule.get('DB_USER')}:${ConfigModule.get('DB_PASS')}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' }),
    ProductModule,
    CategoryModule,
  ],
  controllers: [
    AppController,
    HealthCheckController,
  ],
  providers: [AppService, CustomLogger],
})

从这里的 Nestjs 文档 - https://docs.nestjs.com/techniques/configuration

这些步骤适用于 MySQL 和 TypeORM。

  1. 安装 Nestjs 配置模块 - npm i --save @nestjs/config 它依赖于 dotenv

  2. 在您的根文件夹中创建一个.env文件并添加您的键/值对,例如DATABASE_USER=myusername

  3. 打开 app.module.ts 并导入配置模块

    import { ConfigModule } from '@nestjs/config';
  1. 将以下行添加到app.module.ts的导入部分。 我将它添加为第一个导入。 它将自动加载 .env 文件的内容。
    ConfigModule.forRoot(),
  1. 然后,您可以按照数据库配置部分中通常的 process.env.<variable_name> 开始使用 env 变量,例如
    process.env.DATABASE_USER

有关 ConfigModule 的更多配置,请参见上面的链接。 您可以使用自定义文件/路径并将模块设置为全局可见。

1. 继续使用 ConfigModule

您需要在 npm 脚本中设置NODE_ENV以便它可以用于加载基于 env 的 env 文件。

"scripts": {
  "start:local": "NODE_ENV=local npm run start"
  "start:dev": "NODE_ENV=dev npm run start"
}

现在您可以使用ConfigModule

@Module({
  imports: [
    ConfigModule.forRoot({ envFilePath: `${process.env.NODE_ENV}.env` }), 
MongooseModule.forRoot(`mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' })
    ...
})

2.使用dotenv

npm install dotenv

将一些脚本添加到您的package.json以设置您所在的环境。

"scripts": {
  ...
  "start:local": "NODE_ENV=local npm run start"
  "start:dev": "NODE_ENV=dev npm run start"
}

main.ts文件中导入dotenv 确保在文件顶部执行此操作。

require('dotenv').config({ path: `../${process.env.NODE_ENV}.env` });

3.使用env-cmd

您可以使用env-cmd npm package。

npm install env-cmd

并在package.json中为不同的环境添加一些命令,例如:

"scripts": {
  ...
  "start:local": "env-cmd -f local.env npm run start"
  "start:dev": "env-cmd -f dev.env npm run start"
}
...

现在您可以使用环境变量,例如:

MongooseModule.forRoot(`mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' })

process.env.MONGO_CONNECTION_STRING

更新:

为了克服不同平台的 env set 命令问题,您可以安装cross-env package。

npm install -D cross-env

并更新脚本:

"scripts": {
  "start:local": "cross-env NODE_ENV=local npm run start"
  "start:dev": "cross-env NODE_ENV=dev npm run start"
}

通过使用 nestjs/config package:

npm 安装@nestjs/config

安装 package 后,在 app 模块(app.module.ts 文件)中:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})

export class AppModule {}

之后,可以在整个应用程序中访问 .env 文件。 假设你的 .env 文件看起来像这样。

DB_USER=mohit

访问 DB_USER 变量使用 process.env.DB_USER

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});

您需要使用MongooseModule.forRootAsync(() => {...})而不是MongooseModule.forRoot(...)

这使得 MongooseModule 等待它的 IOC 依赖。

请参阅: https://docs.nestjs.com/techniques/mongodb#async-configuration

要在 app.module.ts 本身中使用 NestJS 配置(dot-env),请使用MongooseModule.forRootAsync({}) 这是我的代码。

  @Module({
  imports: [
    MongooseModule.forRootAsync({
      useFactory: () => ({
        uri: process.env.CONNECTION_STRING,
      }),
    }),
    ConfigModule.forRoot(
      {
        isGlobal: true
      }
    )
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM