I need to define my environment variables in a JSON file which lives in the root directory (each deployment environment can therefore have their own environment variables).
I am currently using environment variables in the .env file to achieve that, but my team claims that the web does not have access to process.env and I need to switch to the JSON method.
I looked around, and it seems that I have to eject to achieve this. Is that still the case? Or is there a way in which I can include a JSON file in the root directory of the project which I can then fetch using whatwg-fetch (or axios).
Yes, the browsers does not have access to process.env, that is why CRA uses webpack to inline the variables at compile time.
Environment variables defined in your .env or .env.local file starting with REACT_APP_ get compiled with your app. See the doc
NODE_ENV is automatically set to production when building, so you might not be able to override that, and PUBLIC_URL is also set.
So, if you have in your .env file
REACT_APP_ENVIRONMENT=staging
REACT_APP_ENABLE_FEATURE=false
In your code, you can do something like
if (process.env.REACT_APP_ENVIRONMENT === 'staging') {
// Do something or something else.
}
What CRA actually does is inline the value of process.env.REACT_APP_ENVIRONMENT directly, so it becomes roughly
if ('staging' === 'staging') {
// Do something or something else.
}
The blocks can be left or removed in production builds depending on what you have defined, so the values cannot be dynamic.
However, if you still want to go with your .json solution, you don't need ajax to use .json files with CRA. Put your .json file in the src folder and you can import it from any file.
import config from './path/to/file.json'
If the filename is dynamic, you can still use dynamic imports
import('./path/to/file.json').then(/* Do something */)
Thanks @bondz :)
As a reminder, it's still possible to dynamically load content as @bondz defined above with the dynamic import, and still use that response in a React class as state. The following works well:
componentWillMount() {
import('../data/db.json').then(
res => this.setState({ data: res })
);
}
A bit more cumbersome, but effectively with the same results as an async way to load your data similar to what a fetch to the JSON file would be!