admin管理员组文章数量:1332383
My aim is to find a way to dynamically pull in environment-specific config values for various 'tracks' of my React app: development, staging and production. The solution most often prescribed involves the use of environment variables, which I don't find great because:
- Some of my config values are sensitive data like API secret keys, database passwords, etc and I'd ideally not be keeping these in plain-text both locally and on a CICD system
- Having to manually set env vars is error prone and doesn't scale well (it's a big project that has more than 20 config-related key-value pairs to set). It's also difficult to document which env vars need to be set, so it's not a convenient solution for a multi-collaborator team as everyone needs to keep track of the list and copy-paste the values into their local machines for shared API keys, etc (or worse, hard-coding/checking them into the source code)
I have tried the following 2 general approaches:
- Use node-config - it looks promising as it's light, flexible, and extensible (it allows defining base values on
default.js
and overriding them withdevelopment.js
,staging.js
,production.js
or with custom env variables). Most importantly, we can store secrets in a remote service (e.g AWS/GCP Secrets Manager, envkey, etc). This solution works well for my Node backend, but so far not for the frontend app built on React - Use dotenv (or dotenv-safe, to allow documenting the structure of .env file in another one
.env.example
that is checked into source control). This is not my favored approach as dotenv discourages using multiple .env files for each environment our project needs. Secondly, I'd likely still have to find another way to feed in the env variables into my CICD system. Redefining the env vars on the [remote] build system feels like doing the work twice - the first being on the .env files used for local development.
Both approaches yield a familiar problem: TypeError: fs.readFileSync is not a function
. According to this related question, it appears that the underlying issue is that the 'fs' module is not designed to work on the browser (both dotenv and node-config are low level modules that use 'fs' under the hood). If we cannot use fs (or rather, modules that rely on it) on the client side: how do scalable/production-grade React projects typically manage config values in a sane way? I know hashicorp/vault exists but it seems a bit of an overkill as we'd likely have to set up our own infrastructure.
I also wonder if there's any open-source tools out there to solve this mon problem...
My aim is to find a way to dynamically pull in environment-specific config values for various 'tracks' of my React app: development, staging and production. The solution most often prescribed involves the use of environment variables, which I don't find great because:
- Some of my config values are sensitive data like API secret keys, database passwords, etc and I'd ideally not be keeping these in plain-text both locally and on a CICD system
- Having to manually set env vars is error prone and doesn't scale well (it's a big project that has more than 20 config-related key-value pairs to set). It's also difficult to document which env vars need to be set, so it's not a convenient solution for a multi-collaborator team as everyone needs to keep track of the list and copy-paste the values into their local machines for shared API keys, etc (or worse, hard-coding/checking them into the source code)
I have tried the following 2 general approaches:
- Use node-config - it looks promising as it's light, flexible, and extensible (it allows defining base values on
default.js
and overriding them withdevelopment.js
,staging.js
,production.js
or with custom env variables). Most importantly, we can store secrets in a remote service (e.g AWS/GCP Secrets Manager, envkey, etc). This solution works well for my Node backend, but so far not for the frontend app built on React - Use dotenv (or dotenv-safe, to allow documenting the structure of .env file in another one
.env.example
that is checked into source control). This is not my favored approach as dotenv discourages using multiple .env files for each environment our project needs. Secondly, I'd likely still have to find another way to feed in the env variables into my CICD system. Redefining the env vars on the [remote] build system feels like doing the work twice - the first being on the .env files used for local development.
Both approaches yield a familiar problem: TypeError: fs.readFileSync is not a function
. According to this related question, it appears that the underlying issue is that the 'fs' module is not designed to work on the browser (both dotenv and node-config are low level modules that use 'fs' under the hood). If we cannot use fs (or rather, modules that rely on it) on the client side: how do scalable/production-grade React projects typically manage config values in a sane way? I know hashicorp/vault exists but it seems a bit of an overkill as we'd likely have to set up our own infrastructure.
I also wonder if there's any open-source tools out there to solve this mon problem...
Share Improve this question asked Oct 11, 2020 at 21:19 kip2kip2 6,9136 gold badges62 silver badges77 bronze badges 2- Create multiple .env file in addition to the basic one. Like .env.dev .env.stage .env.prod. when you create the build, or you start it, pass an env variable through. Command line specifying the env. Then before to build or start, copy the content of the corresponding env file of that evn, into the main .env file. React should pick up correctly the right bones env resilient – quirimmo Commented Oct 11, 2020 at 21:28
- 1 @quirimmo I was hoping to avoid copy-pasting between .env files. Anyway, I found a better solution based on Doppler – kip2 Commented Oct 12, 2020 at 20:15
2 Answers
Reset to default 3Neither of the two solutions offered above really met my requirements, first because I'm using a create-react-app project so don't have much control over webpack configuration. Secondly, I'd much prefer to not keep .env
files locally (let alone in plain text)
Luckily, I came across https://doppler./, a universal secrets management solution that solves my needs as described on the OP:
- it's a cloud-based secrets store + manager that es with a CLI, which allows us to use the same env secrets across the entire pipeline (local development, CICD and production)
- projects e loaded with development, staging and production environments that makes it easy to switch easily between different flavors of the app
Because Doppler works by injecting environment variables into the runtime, I can run it like so, with yarn:
doppler run -- yarn start
For server environments that need to first inject the env vars into a bundled app (e.g the firebase emulator), first do a 'doppler-injected' build:
doppler run -- yarn build
And then run the emulator as usual:
firebase emulators:start
Using separate dotenv
for example, .env.dev
, .env.qa
would be my current approach to a scalable react project. I am assuming you are using webpack
and are facing issues in fetching the files using fs
, as separately fs
is a node server side module.
To resolve this TypeError
issue, in your webpack
config, you can use fs
to access the current working directory,
const fs = require('fs');
const path = require('path');
const reactAppDirectory = fs.realpathSync(process.cwd());
const resolveReactApp = (relativePath) => path.resolve(reactAppDirectory, relativePath);
You need to copy all your assets and build into a spearate public
folder have a web.config and resolve its path using the above resolveReactApp('public')
in contentBase
key of devServer
section of your webpack
config.
You can pass the environment variables using webpack's DefinePlugin or 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']);
To store secrets, I would suggest you check out docker-secrets and using a containerized architecture for deployment, and further when the team expands, it'll be easier to get the project setup as well. Here's a quick setup intro of how to use docker with react and more info on switching from environment variables to docker-secrets for a better system architecture.
本文标签: javascriptHow to set up dynamic environment configurations in ReactStack Overflow
版权声明:本文标题:javascript - How to set up dynamic environment configurations in React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742294726a2448492.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论