In this post I will show an example of a large React Bazel build consisting of more than 8000 components and service files. The sample uses Bazel to create a Rollup production bundle from this relatively large set of files.
Generally a single React application wouldn’t consist of 8000 component, but I have decided to inflate the size of the sample to simulate a sizable monorepo. The high number of components is not unrealistic in a monorepo, but it would likely be spread across multiple applications. Still I decided to go with a single application since it simplifies the demo setup.
In addition to the React application I am also building a simple Express Api that I use to serve the React application.
Building the Sample
The code is written in TypeScript, so the build steps break down to two main parts; TypeScript compilation and Rollup production bundling.
Building the application locally takes a very long time on my aging MacBook Pro, so to reduce the rebuild penalty I have added a remote Bazel cache. This means only the first build is slow. Subsequent builds will be fast since I can download the build artifacts from the remote cache instead of building everything locally. In my case the remote cache is implemented as an nginx server.
The idea is that other people can also use the cache and avoid paying the tax of the first build. A further improvement on this would be to outsource the build to remote builders in the cloud. Check out my article about remote build execution in case you are interested to learn more about that.
I have put the sample on Github in case you would like to try it out yourself.
To make it easier to run the sample, I have dockerized the entire setup, so there is no need to install anything other than Docker itself.
Just follow the following steps:
- Clone the repo and check out the branch called remote
- In terminal 1 run npm run start-remote-cache
- In terminal 2 run npm run start-client
- After the build completes, browse to http://localhost:7001
Once the application starts building you can follow along in terminal 1 to see cache hits and cache missies. GET requests with a 200 status code is a cache hit. After a cache miss you will see a PUT request populating the cache with an artifact that was built locally.
I have included a couple of screenshot below to help you visualize the build process: