Cut down your Webpack build times by half with esbuild-loader

It's been a common practice in the web dev world to transpile Javascript code with tools built with... well Javascript. Webpack is a code bundler that takes in all your code along with dependencies from node_modules and spits out chunks of code depending on your configuration.

The problem with Javascript is that it's slow and that is visible in tools like Webpack and Rollup. But there are new kids on the block, namely esbuild, Vite and Snowpack. Snowpack and Vite internally use esbuild. esbuild is written in Golang which offers significant performance boosts.

There is one problem though: these tools are new and might not have all the plugins you need for your next project. Or, you just don't want to leave the Webpack world yet.

As your project grows larger, your build times get longer. There is a need to reduce build times.

When I say reduce build times, I also mean the time it takes to start your local dev server and the time taken for Hot Module Replacement. esbuild-loader offers significant improvements in all these areas

In comes esbuild-loader

What if you could harness the power of esbuild within webpack? Let's get started with a code example.

I will be using a React boilerplate that uses Webpack and Babel. Feel free to use this on any project of your choice

Clone the repo on your machine with

git clone https://github.com/ReactJSResources/react-webpack-babel.git
cd react-webpack-babel

Install dependencies with NPM

npm install

Now let's run npm run build before adding esbuild-loader to compare build times

webpack 5.4.0 compiled successfully in 6127 ms

Add esbuild-loader

npm i -D esbuild-loader

Change your webpack.config.json file to replace babel-loader with esbuild-loader.

You can find this file in the root of your project. For the boilerplate, it's in the config folder. If you are using create-react-app you will have to eject.

module.exports = {
      module: {
        rules: [
  -       {
  -         test: /\.js$/,
  -         use: 'babel-loader',
  -       },
  +       {
  +         test: /\.js$/,
  +         loader: 'esbuild-loader',
  +         options: {
  +           loader: 'jsx',
  +           target: 'es2015'
  +         }
  +       },
          ...
        ],
      },
    }

Webpack uses Terser to minify JS and CSS. You can replace that with the ESBuildMinifyPlugin for a much faster minification process.

+ const { ESBuildMinifyPlugin } = require('esbuild-loader')
    module.exports = {
      ...,
  +   optimization: {
  +     minimizer: [
  +       new ESBuildMinifyPlugin({
  +         target: 'es2015',
  +         css: true 
  +       })
  +     ]
  +   },
    }

Now run npm run build to test it again

webpack 5.4.0 compiled successfully in 1904 ms

That's a pretty significant boost!

For an empty project, we reduced the build times to a third of the original build time. For larger and more realistic projects, you can expect build times closer to half of that with babel-loader.

The time taken to start the dev server was less than a second!

We can expect bundlers like Vite and Snowpack to grow in popularity with time. Till they become mainstream, esbuild-loader offers a great way to speed up builds.

Don't forget to star privatenumber/esbuild-loader on Github

22