DEV Community

Cover image for Injecting Environment Variables into a React App
Lev Eidelman Nagar
Lev Eidelman Nagar

Posted on

Injecting Environment Variables into a React App

When creating a react app using create-react-app, we may sometimes want to inject some environment variables at build time.
For instance, our team wanted to console.log the build time, app version and some git information when the app starts.

This is the solution we came up with.

The Build script

We added a node script to scripts/build.js. The script uses shelljs to append information to the environment and run react-scripts and simple-git to execute git commands.

const path = require('path');
const shell = require('shelljs');
const simpleGit = require('simple-git');
const { version } = require('../package.json');

const args = process.argv.slice(2);
const isDev = args.includes('--dev');

if (!shell.which('git')) {
  shell.echo('Cannot build without git');
  shell.exit(1);
}

if (!shell.which('yarn')) {
  shell.echo('Cannot build without yarn');
  shell.exit(1);
}

const workingDir = path.resolve(__dirname, '../');
const git = simpleGit(workingDir);

function getCurrentBranch() {
  return new Promise((fulfill, reject) => {
    git.status((err, status) => {
      if (err) {
        reject(err);
        return;
      }

      fulfill(status.current);
    });
  });
}

function getCurrentCommit() {
  return new Promise((fulfill, reject) => {
    git.revparse(['HEAD'], (err, hash = '') => {
      if (err) {
        reject(err);
        return;
      }
      fulfill(hash.slice(0, 7));
    });
  });
}

(async () => {
  try {
    const branch = await getCurrentBranch();
    const commit = await getCurrentCommit();
    const buildTime = new Date().toUTCString();

    shell.env.REACT_APP_VERSION = version;
    shell.env.REACT_APP_GIT_BRANCH = branch;
    shell.env.REACT_APP_GIT_COMMIT = commit;
    shell.env.REACT_APP_BUILD_TIME = buildTime;

    if (isDev) {
      shell.exec('yarn react-scripts start');
      return;
    }

    shell.exec('yarn react-scripts build');
  } catch (err) {
    shell.echo('Failed to gather build info', err);
    shell.exit(1);
  }
})();

Enter fullscreen mode Exit fullscreen mode

We substitute react-script in package.json for our build script:

...
  "scripts": {
    "start": "node ./scripts/build --dev",
    "build": "node ./scripts/build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
...

Enter fullscreen mode Exit fullscreen mode

In the app

We added src/utils/printBuilInfo.js. It prints out our environment variables in a style inspired by Vue devtools.

function print(title, info) {
  // eslint-disable-next-line
  console.log(
    `%c ${title} %c ${info} %c`,
    'background: #f26d21; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
    'background: #009eed; padding: 1px; border-radius: 0 3px 3px 0;  color: #fff',
    'background:transparent',
  );
}

export default function printBuildInfo() {
  print('Version', process.env.REACT_APP_VERSION);
  print('Branch', process.env.REACT_APP_GIT_BRANCH);
  print('Commit', process.env.REACT_APP_GIT_COMMIT);
  print('Build Time', process.env.REACT_APP_BUILD_TIME);
}

Enter fullscreen mode Exit fullscreen mode

We use it in src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import App from './App';
import printBuildInfo from './utils/printBuildInfo';
import './styles/index.scss';

printBuildInfo();

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
rodriguesl3 profile image
Lucas Rodrigues

Hey Lev, thank you for your contribution. An improvement that you could do in your post is provide some comments in your script. It helps for beginners read easily your logic.

Thank you again this article helped me to solve an issue that I have.