Custom react-scripts to instrument React app using Istanbul

Istanbul is a code coverage utility for JavaScript apps. It is integrated with most unit-testing frameworks like Jest. It is also possible to produce an instrumentation build with a babel plugin named babel-plugin-istanbul. This works for any React app scaffolded with Webpack configuration. However, it does not work for create-react-app (CRA). CRA does not expose webpack.config or .babelrc file, files where we can add the istanbul plugin. After consulting with Facebook team, I decided to create a custom react-scripts package named react-scripts-istanbul.

Creating a custom react-scripts package

The react-scripts-istanbul package does the following:

  1. Include babel-plugin-istanbul if the environment is not production.
  2. Produce a regular production build when –coverage flag is not specified.
  3. Produce an instrumentation build when –coverage flag is specified.
  4. Start the webpack-dev-server with instrumented source code.

While creating the react-scripts package, I encountered a few obstacles. It was caused by working on top of master branch with some unreleased changes in react-dev-utils package. For those who want to create a custom react-scripts package, make sure you checkout the latest released tag and build it up from there.

Another thing that was a problem for me was how to test it. I could not figure how to run the tests for react-scripts package. So, I set out to publish the package in NPM before testing it. If you know how to test react-scripts, please let me know in a blog post or in comments.

I made a few changes in two files: config/webpack.config.js and build.js

  1. webpack.config.js: Added the plugin for development environment.
  2. webpack.config.js: For development environment, specified the output path.
  3. In build.js, switched the environment back to development if –coverage flag is specified.
  4. Since build.js is written only for production environment, made some changes so that it works for development environment also.

With the above changes, I published the NPM package.

How to use react-scripts-istanbul

CRA allows using custom react-scripts like so.

create-react-app 
--scripts-version react-scripts-istanbul 
coveragedemo

After installation, the dependencies should like so.

Project with react-scripts-istanbul
cd coveragedemo
yarn start

This should start localhost at port 3000. Open the browser console and type __coverage__ and press Enter. You should see the coverage object like so.

coverage object

Next, do a regular production build and use utility like serve to run a server.

yarn build
cd build
serve

Go to localhost:5000 and look for coverage object like before. Since this is a production build, you should not see any coverage object.

To produce an instrumentation build, use the –coverage flag.

yarn build --coverage
cd build
serve

Go to localhost:5000 and look for coverage object. You should now see the coverage object.

Using packages like istanbul-coverage-display, we can view the coverage object as we interact with the app.

Using istanbul-coverage-display

Install the package.

yarn add istanbul-coverage-display

In App.js, import the CoverageSummary component.

import { CoverageSummary } from 'istanbul-coverage-display';
import 'istanbul-coverage-display/dist/bundle.css';

Add the CoverageSummary component to the App component just before the closing div tag.

        <CoverageSummary />
      </div>

When you run the app, you should see the “Show coverage” button. On clicking on the button, you should view the coverage summary in a nice widget.

Coverage Display

There is also a CoverageDetail component which can be placed below the logo.

<CoverageDetail />

The coverage is low because of the service worker in CRA.

Related Posts

One thought on “Custom react-scripts to instrument React app using Istanbul

  1. Hi,
    nice tutorial. I am using your scrips, the problem is that the build script doesn’t transpile the code and everything fails when I execute my app with nginx.
    There is anything I can do to transpile the instrumented code?

    Thanks,
    Marc

Leave a Reply

Your email address will not be published.