Create a mix-manifest.json file with esbuild
Tags: esbuild
Published: 2022-07-06 07:50:25

---
title: Create a mix-manifest.json file with esbuild
published: true
date: 2022-07-02 12:00:00 UTC
tags: esbuild
canonical_url: https://stefanzweifel.dev/posts/2022/07/02/create-a-mix-manifestjson-file-with-esbuild
---

This website is very simple. It's just HTML and CSS. No JavaScript at all.  
To generate the HTML, I (currently) use [Jigsaw](https://jigsaw.tighten.com/) and Laravel Blade. For the CSS I use [Tailwind CSS](https://tailwindcss.com/).

Up until a few weeks ago I've used [Laravel Mix](https://laravel-mix.com/), and therefore Webpack, to compile the CSS file. I've been using Mix just for one feature: [versioning](https://laravel-mix.com/docs/6.0/versioning).

By adding `.version()` to my configuration file, Laravel Mix would create a `mix-manifest.json` file when creating a new build. The contents of that file looks like this:

```json
{
    "/css/main.css": "/css/main.css?id=9bdded1b8e8a06a52e67"
}
```

It contains a map of paths to CSS or JavaScript files where the path has been augmented with an `id`-parameter and a hashed value. The hashed value represents the checksum of the referenced file (`css/main.css` in this example) .

When creating a new build with Jigsaw, the generated HTML will load the CSS file with the hashed value. This makes cache busting super easy, as everytime the CSS file changes and new classes are added or removed, the hash changes. The browser will always load the up-to-date CSS file.

As mentioned, Laravel Mix is a wrapper around Webpack. Laravel Mix and Webpack are great. I'm thankful for their existence and all the work that has been put into in them in the last years. But Webpack is slow.

Building the CSS through Webpack takes between 1-2 seconds. Building the CSS with the Tailwind CLI directly drops this to 50ms. Switching to the CLI would be a big win on the performance side, but I would lose the cache busting feature.

On top of building the CSS file comes the time to create a new build with Jigsaw. A complete rebuild of this site takes between 3-5 seconds.

This long feedback loop got annoying when I tweaked the design. I switched from editor to browser too fast. I was still looking at the old design or content while the new version was building.

To fix this issue, I've switched from Laravel Mix to [esbuild](https://esbuild.github.io/) and wrote [my own plugin](https://github.com/stefanzweifel/esbuild-mix-manifest-plugin) to recreate the `mix-manifest.json` file.

I created a new `build.js` file that contains the following code:

```js
#!/usr/bin/env node

const { build } = require('estrella');
const postcss = require('esbuild-postcss');
const mixManifestPlugin = require('@stefanzweifel/esbuild-mix-manifest-plugin');

build({
    entryPoints: {
        'css/main': 'resources/css/main.css',
    },
    outdir: 'source/assets/build',
    outbase: 'source/assets/build',
    metafile: true,
    minify: true,
    plugins: [
        postcss(),
        mixManifestPlugin(),
    ],
});
```

I'm using [estrella](https://github.com/rsms/estrella) to get the `build` method. I give the method my CSS file as an entrypoint, add the `postcss` and `mixManifest` plugins and that's it.

In my `package.json` file I've added 2 new script commands: One to create a new CSS-build. And a second command to watch the project for changes and compile the CSS and the site.

```json
"scripts": {
    "prod": "node build.js",
    "watch": "nodemon --ignore source/assets/build/ \
     --watch resources --watch source \ 
     -e md,php,css \ 
     -x 'npm run prod && composer run build'"
},
```

Switching from Laravel Mix to esbuild cut the full build time of my site in half (from 4-5 seconds to 2 seconds).

If you work in a Laravel project that doesn't need a bundler like Webpack, Laravel Mix or [Vite](https://vitejs.dev/) and you would like to have a simple way to cache bust your assets, give esbuild and my [mix-manifest](https://github.com/stefanzweifel/esbuild-mix-manifest-plugin) plugin a try.