Multi-Environment Deployments with React

If you are using Create-React-App to scaffold your react application there is built in support for changing environment variables based on the NODE_ENV values, this is done by using .env files.  In short this process works by having a .env, .env.production, .env.development set of files.  When you run/build your application CRA will set the NODE_ENV value to either development or production and based on these values the correct .env file will be used.

This works great, when you have a simple deploy setup. But many times in enterprise level applications you need support for more than just 2 environments, many times it is 3-4 environments.  Common logic would suggest that you can accomplish this via the built in mechanism by having additional .env files and changing the NODE_ENV value to the value you care about.  However, CRA does not support this with doing an eject, which will eject all the default conventions and leave it to you to configure your React application.  Maybe this is a good idea, but in my case ejecting was not something I wanted to do.

Because I did not want to do an eject I needed to find another solution, and after a fair amount of searching I found a solution that seems to work for me and my needs and is about the amount of effort as I wanted 🙂

Background:

For my projects needs I needed to support 4 total environments, local, test, non-production, production.  I needed to be able to build and deploy to test, non-prod, and prod via our CI/CD pipeline.  This means that we could not manually make changes.

Solution:

I found a npm package called react-app-env (repo).  This package will take care of changing the config file I want to use based on my build targets.  Please note that this does NOT change the NODE_ENV value, just which config file to merge.

My setup I created the following files

  • .env (do not commit this to source)
  • .env.template (this is not used in the build pipelines, this is for guidance and documentation)
  • .env.development
  • .env.test
  • .env.nonprod
  • .env.prod

Now that I have my files setup I need to get the values from the right file into my build.

If I run npm start from the command line the values in my .env and .env.development files will be used because of the way CRA works.  This solution works in development/local mode because I am not worried about packaging and deploying my code.

In order to get my package build correctly for deployment I want to make sure my correct .env.* file is used.  To do this I want to make changes to my package.json file in the scripts section.

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build-prod": "node -r dotenv/config ./node_modules/.bin/react-scripts build dotenv_config_path=.env.prod",
    "build-nonprod": "node -r dotenv/config ./node_modules/.bin/react-scripts build dotenv_config_path=.env.nonprod",
    "build-test": "node -r dotenv/config ./node_modules/.bin/react-scripts build dotenv_config_path=.env.test",
  },

Now that I have my package.json file updated I can build my code and based on the script I run the correct .env.* values will be packaged.  The magic above is the way we configure our build-* commands by changing the dotenv_config_path values to be the correct file.

npm run build-prod

npm run build-nonprod

​​​​​​​​​​npm run build-test

To verify that my correct values are used I can open up the .js file in the ./build/static/js file and search for my changes.

There may be other ways to solve this same problem, but this works for my needs and is about as simple as I wanted.

Till next time,

One thought on “Multi-Environment Deployments with React

  1. Pingback: Interesting links of the week (04/09 – 04/15, 2018) – same stuff, different day

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s