create react app cannot read environment variable after build

Viewed 12079

I have a react app , created with create-react-app then I build the app with command: npm run build

It's using serve to run the app after build, if we start the app with development code by running ENV=production npm run start it can read the process.env.ENV variable beacause I'm adding this plugins to webpack dev config

   new webpack.DefinePlugin({
      'process.env':{
        'ENV': JSON.stringify(process.env.ENV),
      }
    }),

I also add the script above to webpack prod config, but if I try this command after build ENV=prod serve -s build, it cannot read the environment variable

How to fix this?

4 Answers

If you set all the environment variables inside the app.config.js, you can replace them after the build in the main.????????.chunk.js file.

A sample app.config.js could look like:

export default {
  SOME_URL: "https://${ENV_VAR_1}"
  SOME_CONFIGURATION: "${ENV_VAR_2}",
}

Leave the app.config.js file as is, without replacing the environment variables with their actual values. Then, create the optimized production build:

npm ci # if not already installed
npm run build

If the default webpack configurations are used, the contents of app.config.js will be bundled in build/static/js/main.????????.chunk.js. The values of the environment variables can be be envsubst, with a bash script like this:

main_chunk=$(ls build/static/js/main.*.js)
envsubst <$main_chunk >./main_chunk_temp
cp ./main_chunk_temp $main_chunk
rm ./main_chunk_temp

Note: In the above example, envsubst reads the actual variables set in the environment at runtime and literally replaces ${ENV_VAR_1} and ${ENV_VAR_2} with them. So, you can only run this once as the chunk is being over-written.

You can add a .env file to the root of your project and define your environment variables there. That will be your default (production) environment variables definition. But then you can have a local file called .env.local to override values from the default.

When defining your environment variables, make sure they start with REACT_APP_ so your environment variable definitions would look like this:

REACT_APP_SERVER_URL=https://my-awesome-app.herokuapp.com

Also, add this to .gitignore so you don't commit your local overrides:

.env*.local

Reference: Adding Development Environment Variables In .env (create-react-app)

From create-react-app documentation:

Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined for you, and any other environment variables starting with REACT_APP_.

You can read them from process.env inside your code:

render() {
  return (
    <div>
      <small>You are running this application in <b>{process.env.NODE_ENV}</b> mode.</small>
      <form>
        <input type="hidden" defaultValue={process.env.REACT_APP_NOT_SECRET_CODE} />
      </form>
    </div>
  );
} 
Related