如何在React中设置动态环境配置

时间:2020-10-11 21:19:53

标签: javascript reactjs configuration environment-variables dotenv

我的目标是找到一种方法,为我的React应用程序的各个“轨道”动态提取特定于环境的配置值:开发,登台和生产。最常用的解决方案涉及环境变量的使用,我认为这不是很好,因为:

  1. 我的一些配置值是敏感数据,例如API密钥,数据库密码等,我 理想情况 不要在本地和本地以纯文本格式保存这些数据在CICD系统上
  2. 必须手动设置env vars容易出错,并且伸缩性不好(这是一个大项目,需要设置20多个与配置相关的键值对)。记录需要设置哪些环境变量也很困难,因此对于多协作者团队来说,这不是一个方便的解决方案,因为每个人都需要跟踪列表并将值复制并粘贴到本地机器中以共享API密钥等。 (或更糟糕的是,将其硬编码/签入源代码)

我尝试了以下2种常规方法:

  1. 使用node-config-它轻巧,灵活且可扩展(因为它允许在default.js上定义基本值并用development.jsstaging.js,{ {1}}或使用自定义环境变量)。最重要的是,我们可以将机密存储在远程服务中(例如,AWS / GCP机密管理器,envkey等)。这个解决方案对我的Node后端很好,但是到目前为止,对于在React上构建的前端应用来说还不行。
  2. 使用dotenv(或dotenv-safe,以允许在另一个进入源代码管理的production.js中记录.env文件的结构)。对于项目所需的每种环境,这都不是我喜欢的dotenv discourages using multiple .env files方法。其次,我可能仍然必须寻找另一种方法来将env变量输入到CICD系统中。在[remote]构建系统上重新定义env var感觉就像是在做两次工作-第一个是在用于本地开发的.env文件上。

两种方法都会产生一个熟悉的问题:.env.example。根据{{​​3}},看来根本的问题是this related question(dotenv和node-config都是在底层使用'fs'的低级模块)。 如果我们不能在客户端使用fs(或更确切地说,依赖它的模块):可伸缩/生产级React项目通常如何以理智的方式管理配置值?我知道{{3 }}存在,但似乎有点过大,因为我们可能必须建立自己的基础架构。

我还想知道是否有开源工具可以解决这个常见问题...

2 个答案:

答案 0 :(得分:1)

以上提供的两个解决方案均未真正满足我的要求,首先是因为我使用的是create-react-app项目,因此对webpack配置没有太多控制权。其次,我更希望不要在本地保留.env个文件(更不用说纯文本格式了)

幸运的是,我遇到了https://doppler.com/,这是一种通用机密管理解决方案,可以按照OP中的描述满足我的需求:

  1. 这是带有CLI的基于云的秘密存储+管理器,它使我们可以在整个管道(本地开发,CICD和生产)中使用相同的环境秘密
  2. 项目带有开发,暂存和生产环境,可轻松在不同版本的应用之间轻松切换

因为多普勒通过将环境变量注入运行时来工作,所以我可以使用yarn像这样运行它:

doppler run -- yarn start

对于需要首先将env var注入捆绑的应用程序(例如firebase模拟器)的服务器环境,请首先执行“多普勒注入”构建:

doppler run -- yarn build

然后像往常一样运行模拟器: firebase emulators:start

答案 1 :(得分:0)

使用单独的dotenv例如.env.dev.env.qa是我当前的可伸缩React项目方法。我假设您正在使用webpack,并且在使用fs来获取文件时遇到了问题,因为fs是节点服务器端模块。 要解决此TypeError问题,请在您的webpack配置中,使用fs访问当前工作目录,

const fs = require('fs');
const path = require('path');
const reactAppDirectory = fs.realpathSync(process.cwd());
const resolveReactApp = (relativePath) => path.resolve(reactAppDirectory, relativePath);

您需要复制所有资产并将其构建到带有web.config的矛状public文件夹中,并使用上述resolveReactApp('public')键中的contentBase键中的以上devServer来解析其路径。 webpack配置中的}部分。

您可以使用webpack的DefinePlugin或EnvironmentPlugin传递环境变量,

new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  'process.env.DEBUG': JSON.stringify(process.env.DEBUG)
});

new webpack.EnvironmentPlugin(['NODE_ENV', 'DEV']);

要存储秘密,我建议您检查docker-secrets并使用容器化体系结构进行部署,并且随着团队的扩大,更容易进行项目设置。这是how to use docker with react的快速设置介绍,以及有关switching from environment variables to docker-secrets的更多信息,以提供更好的系统架构。