We'll see you soon 👋
Create React App: Run-time vs Build-time Environment Variables
This post will show you how I migrate create-react-app custom environement variables from build-time to be configurable at run-time. According to create-react-app docs we can not embed environement variables during runtime. so defining them with the prefix REACT_APP_
will expose them only in build-time where you can access them by process.env.REACT_APP_KEY
Note: I will use these aliases throughout the rest of article:
- env vars instead of environment variables
- env/s instead of enviroment/s
Initializing Envirnoment Variables in Build Time
To define env vars in build-time, just put your own env vars keys into .env
file located in your home path, and prefixed by REACT_APP_
. The env vars in this file will be exposed into your JS code in development enviroment only. There are more configurable ways to define env vars in test, production envs and even override all the three envs locally on your machine as descriped in create-react-app docs as the following:
- test env > add the env vars in
.env.test
- prodcution env > add the env vars in
.env.production
- locally-test-override env > add env vars in
.env.local.test
- locally-production-override > add env vars in
.env.local.production
- locally-development-override > add env vars in
.env.local.development
There is something to be considered; .env
files have precedence rules based on which npm/yarn command you will run as the following:
yarn/npm start
:.env.development.local
,.env.development
,.env.local
,.env
yarn/npm build
:.env.production.local
,.env.prodcution
,.env.local
,.env
yarn/npm test
:.env.test.local
,.env.test
,.env
when the precedence is from the left to the right.
Note: .env.local
is missing from yarn/npm test
and don't know why! but it is mentioned in create-react-app docs!
A final example will be a .env
file with env vars keys and values like this:
REACT_APP_KEY = some - value;
Migrate to Run Time Environment Variables
This is a hack solution because the definition of env vars in browsers does not even exist. It is something like a fake abstraction as mentioned here. We will keep our .env
file only with the default develepment env vars as it is our main concern now!
We'll see you soon 👋
How this will be done?
I will extract the env vars in .env
file into a new javascript config file using a simple bash script as below imported from here
#!/bin/bash
set -e
# Recreate config file
rm -rf ./env-config.js
touch ./env-config.js
# Add assignment
echo "window._env_ = {" >> ./env-config.js
# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
fi
# Read value of current variable if exists as Environment variable
value=$(printf '%s\n' "${!varname}")
# Otherwise use value from .env file
[[ -z $value ]] && value=${varvalue}
# Append configuration property to JS file
echo " $varname: \"$value\"," >> ./env-config.js
done < .env
echo "}" >> ./env-config.js
This will create env-config.js
file that you will need to embed it like below:
<script src="%PUBLIC_URL%/env-config.js"></script>
into your public/index.html
. Finally this is how the file will look like:
window.__env__ = {
REACT_APP_KEY: value
};
Putting All Together
To get all of these running in development, you will need to:
• update yarn/npm start
command to
./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start
• update all
process.env.REACT_APP_KEY;
to
window.__env__.REACT_APP_KEY;
Setup Tests Environment Variables
Doing all of the above will not guarantee running your test suites correctly, actually, you will see an error that can't read property REACT_APP_KEY
of undefined. This is because __env__
is not exposed in test environment which by the way is a build-time process. There is a hack solution for this problem which reusing .env
file to assign all the values from it to __env__
into your setupTests.js
like below:
window.__env__ = {
REACT_APP_KEY: process.env.REACT_APP_KEY
};
Article link: https://syncatallah.cc/writings/create-react-app-run-build-envs
Related Jobs
Related Articles
Related Issues
- Started
- 0
- 8
- Intermediate
- Submitted
- 1
- 1
- Intermediate
- Started
- 0
- 24
- Intermediate
Get hired!
Sign up now and apply for roles at companies that interest you.
Engineers who find a new job through Functional Works average a 15% increase in salary.
Start with GitHubStart with TwitterStart with Stack OverflowStart with Email