Reduce Builds

Introduction

CI/CD pipelines are great for automation and are an essential part of any software delivery process. This post covers React, but the principles can be applied to any application stack.

The Problem: As your application grows in size your build minutes will also start to balloon. As well as the raw cost of build minutes (eg: GitLab, Azure DevOps, GitHub) build times can also affect productivity, validation cycles, and ultimately speed to market.

Here’s my list of 5 things to help reduce pipeline build minutes for your React application:

  1. Enforce linting rules and code styles in your IDE
  2. Catch lint, code style and unit test errors locally
  3. Catch missing environment variables at build time
  4. Cache dependencies
  5. Review your bundling tools

1) Enforce linting rules and code styles in your IDE

“Developers who get feedback from their IDE don’t waste valuable build minutes”

Use VS Code and install the following extensions to get developers to resolve linting and code style issues before fail in your pipelines:

2) Catch lint, code style and unit test errors locally

After the IDE extensions have done some heavy lifting, the next line of defence is githooks. These can be used to trigger automation locally, rather than blocking your CI/CD pipelines with broken builds.

Husky is a simple tool to help you configure your githooks.

3) Catch missing environment variables at build time

If your using CRA you’ll know how to add custom environment variables to your project.

As you project grows in size and complexity the number of environment variables you need will also grow. This will include: external API endpoints, number of environments, number of developers in your team(s).

Don’t wait for your production build to find our environment variables are missing, catch them at the very start of your build pipeline.

Here’s a simple Node.js script to add as a first step in your pipeline to check all required environment variables have been configured:

const requiredVars = [
  "REACT_APP_BASE_URL",
  "REACT_APP_CMS_API_URL"
];

const getMissingEnvVars = (envVars) => {
  const missingEnvVars = [];

  envVars.map(envVar => {
    if(!process.env[envVar]){
      missingEnvVars.push(envVar);
    }
  });

  return missingEnvVars;
};

missingEnvVars = getMissingEnvVars(requiredVars);

if (missingEnvVars.length > 0) {
  console.error(
    `ERROR: Missing environment variable(s): ${missingEnvVars.join(", ")}`
  );
  process.exit(1);
}

process.exit(0);

TIP: You could also externalise your required environment variables in a JSON file and run a similar check at runtime from within your application.

4) Cache dependencies

Use npm ci to cache your npm dependencies:

5) Review your bundling tools

esbuild could significantly (10-100x) reduce your build time.

Use craco (Create React App Configuration Override) to replace your CRA Webpack configuration.

Summary

Reducing the number of broken builds and decreasing build time will make your development team more productive and increase your speed to market.

Check out these posts if you’re interested in automation with CI/CD: