DEV Community

Marcin Wosinek
Marcin Wosinek

Posted on • Edited on • Originally published at how-to.dev

How to build code generated by create-react-app with esbuild

esbuild is js bundler that is getting more and more traction because of it impressive build speed. create-react-app (CRA) is well-established script to generate a new react application. In this article, we will take a look on what tweaks are needed to CRA output to pass build with esbuild.

Alternatives

There are some react app generators that use esbuild out of the box:

and those can be a good idea if you are starting a new project, but for already existing apps they probably will not be of much help.

Generting new application

To simplify our example, let's generate new application with CRA:

$ npx create-react-app esbuild-cra

Creating a new React app in /home/marcin/workspace/github/tmp/esbuild-cra.

Installing packages. This might take a couple of minutes.
...

We suggest that you begin by typing:

  cd esbuild-cra
  npm start

Happy hacking!
Enter fullscreen mode Exit fullscreen mode

The next step is to install esbuild:

$ npm install --save-dev esbuild
added 1 package, and audited 1962 packages in 4s

146 packages are looking for funding
  run `npm fund` for details
...
Enter fullscreen mode Exit fullscreen mode

Adding test HTML

For testing the esbuild we will create a dist folder, and put there manually created index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <title>React App</title>
    <link href="main.css" rel="stylesheet" />
  </head>
  <body>
    <div id="root"></div>
    <script src="main.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

I created it based on html output of npm run script, and replace all dynamically created file references with static one that we will build in a moment.

Build script

To build the application, I'll leave the original npm scripts as they were & add temporarily esbuild script for testing. I recommend doing the same if you decide to migrate your app - it will allow for a smooth testing before replacing original builds. Plus you will want to replace dev script too - something that is not covered in this article, and you will need to figure it out on your onw.

To package.json, I add:

  "scripts": {
    ....
    "esbuild": "esbuild src/index.js --bundle --outfile=dist/main.js --loader:.html=text --loader:.js=jsx --loader:.svg=dataurl"
  }
Enter fullscreen mode Exit fullscreen mode

The build script parts means as follow:

  • src/index.js - the entry point of our build. From there all our files are found
  • --bundle - the files are all bundled into one, output file
  • --outfile=dist/main.js - the location where the output files should be saved
  • --loader:.html=text - a loader that will read all HTML files are strings equal to the file content
  • --loader:.js=jsx - the JSX load for JS files - as CRA uses this extension for JSX files
  • --loader:.svg=dataurl - loader that includes SVG files as data url links (data:image/svg;base64....)

With this script in place we already can successfully run npm run esbuild:

$ npm run esbuild

> esbuild-cra@0.1.0 esbuild
> esbuild src/index.js --bundle --outfile=dist/main.js --loader:.html=text --loader:.js=jsx --loader:.svg=dataurl


  dist/main.js   902.9kb
  dist/main.css   1019b 

⚡ Done in 61ms
Enter fullscreen mode Exit fullscreen mode

Add explicit import

If you open the test page as it is now, you will see a white screen and the following error in console:

Uncaught ReferenceError: React is not defined
    App http://localhost/github/tmp/esbuild-cra/dist/main.js:20611
    renderWithHooks http://localhost/github/tmp/esbuild-cra/dist/main.js:12714
    mountIndeterminateComponent http://localhost/github/tmp/esbuild-cra/dist/main.js:14834
...
Enter fullscreen mode Exit fullscreen mode

luckily it's easy to fix, we just need to import React in all places that are referencing it. In our case, just add to src/App.js this line as the first line:

import React from "react";
Enter fullscreen mode Exit fullscreen mode

Links

Summary

In this article, we have seen how to build esbuild an app generated with create-react-app. If you are interested in other articles on this topic, let me know in the comments.

You can see the application in action here, and the repository here

Top comments (0)