Pitfalls of `process.env` every React developer should know
Arnel Enero
Posted on September 14, 2022
Pitfall #1: It does not exist in the browser
Unlike in Node.js, there is no such thing as process.env
object in the browser. One neat webpack trick, however, allows us to "emulate" this construct right in our React app.
Webpack's DefinePlugin
injects environment variables by token replacement of process.env.SOME_ENV_VAR
. The final compiled JS will not have any reference to process.env
because, remember, it does not exist in the browser. So if we have something like this:
console.log(process.env.SOME_ENV_VAR);
webpack will compile that to something like this:
console.log('value of SOME_ENV_VAR');
Pitfall #2: We cannot assign values to it in React code
This one is really just a natural side-effect of pitfall #1. Since process.env
will not exist in the compiled JS code, it follows that it doesn't make sense to try overriding environment variables inside our React app like this:
process.env.REACT_APP_ENV_VAR = 'cannot do this';
Pitfall #3: It may get compiled in a way you didn't expect
There is one significant pitfall that we need to be wary of: We need to make sure that all environment variables referenced in our source code are defined in our .env files or elsewhere.
If DefinePlugin
cannot find a referenced env var's value, it will not token-replace any references with undefined
. For example, if we have not defined REACT_APP_NOT_FOUND anywhere, but we have this code:
console.log(process.env.REACT_APP_NOT_FOUND);
will not translate to this:
console.log(undefined);
Instead, webpack will string-replace just the process.env
part of the token with the entire key-value mapping of env vars. So the translation is actually something like this (even after minification):
console.log(
{
NODE_ENV: ‘development’,
REACT_APP_NAME: ‘My App’,
REACT_APP_ID: ‘232809283923’,
// ... possibly a long list of other values
}.REACT_APP_NOT_FOUND
);
Now imagine if we have lots of checks like this throughout our code:
if (process.env.REACT_APP_SOME_OPTIONAL_FLAG) {
/* . . . */
}
and we only define env vars in our .env file for flags that are true, thinking it’s fine because the logic above only cares about the existence of the flag, not its value.
But take the above compiled code containing the entire env vars object literal, and multiply it by who knows how many possibly-undefined env vars... for sure it’s going to hurt our bundle size.
NOTE: The above behavior is based on how process.env
is typically configured with DefinePlugin
, such as in Create React App. YMMV.
Posted on September 14, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 18, 2024