nestjs 配置与 dotenv

nestjs configuration with dotenv

参考official NestJS documentation,建议使用ConfigService,以便使用环境变量。

因此在代码中,我们访问 .env 文件中定义的所有变量,如:

config.get('PORT')

但不建议在生产环境中使用.env。那么如何部署呢?

为什么不直接使用 dotenvprocess.env.PORT 的标准方法?

有两个问题使 ConfigService 不太有用。

第一

当任何环境中都不存在 .env 文件时,readFileSync

dotenv.parse(fs.readFileSync(filePath))

将失败:

[Nest] 63403 [ExceptionHandler] path must be a string or Buffer
TypeError: path must be a string or Buffer
    at Object.fs.openSync (fs.js:646:18)
    at Object.fs.readFileSync (fs.js:551:33)
    at new ConfigService (../config/config.service.ts:8:38)

即使例如process.env.API_KEY 可用

this.configService.get('API_KEY')

不会return任何东西。所以 ConfigService 强制你使用 prod.env 文件,dotenv 反对:

No. We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. Your config should vary between deploys, and you should not be sharing values between environments.

https://github.com/motdotla/dotenv#should-i-have-multiple-env-files

第二

您必须导入配置模块并注入服务才能使用它。当你像这样使用环境变量时

imports: [
  MongooseModule.forRoot(process.env.MONGO_URI, { useNewUrlParser: true }),
  ConfigModule,
],

配置服务没用。

在此处阅读有关环境配置的更多信息:https://12factor.net/config

But this is not recommended to use .env in production environnement. So how to deploy that way ?

实际上,不建议提交您的 .env 文件。在生产中使用它们非常好:-)。

Why not use the standard method with dotenv and process.env.PORT?

它允许解耦您的核心代码与负责提供配置数据的代码。因此:

  • 核心代码更容易测试:做一些process.env的手册changes/mocking是such - a - 痛苦,而嘲笑“ConfigService”非常容易
  • 你可以想象在未来使用环境变量以外的任何东西,只需替换专用 class 中的单个方法(或几个 getter),而不是替换所有出现的 process.env.*在您的代码中 // 公平地说,这不太可能发生,因为使用了 env。变量是加载配置数据的最常见方式,但仍然。

使用 @nestjs/config(a.k.a。ConfigModule)使环​​境变量可用于您的应用程序,无论它们来自 .env 文件还是在环境中设置。在本地使用 .env 文件,在生产中使用环境。