Go to content
.

If you like fast websites you probably also like Eleventy. Eleventy is my go to tool if I want to quickly build a fast and easy to maintain small website. Every time I create a new website I start with the simplest possible setup an expand it when required, which at some point also leads me to implement some kind of cache busting technique. Cache busting is necessary when you configure caching of static assets, such as CSS, JavaScript or images, and you want a way to tell the browser to load the newest version of these assets. Eleventy does not include any asset handling by default, this gives us the freedom to use whatever we want, but it also requires us to set something up. Max Böck describes a couple of different variants in his blog post Asset Pipelines in Eleventy.

Another method is defining a custom template format, for example, described in the Eleventy documentation in the chapter on custom template languages and there are a couple of plugins that integrate one or the other asset toolchain with Eleventy (for example, PostCSS), but none are dead-simple pure cache busting with the option to add a bit of processing later. This is why I created a plugin to do just that.

I wanted to have one line configuration for the simple use case and the following line processes CSS and JavaScript files and it adds a hash based on the file content to the file name and in addition it will also save a manifest.json with a map from original to hashed file name.

eleventyConfig.addPlugin(cssPipelinePlugin, { extensions: ['css', 'js'] });

In our template we can link a JavaScript file by using the hashFileName filter:

<script src="{{ "/assets/main.js" | hashFileName }}" async></script>

The plugin accepts an option called compilerFns, which is an object of functions that can compile a certain file type. For example, let's say we want to process CSS files with PostCSS:

eleventyConfig.addPlugin(cssPipelinePlugin, {
  extensions: ['css', 'js'],
  compilerFns: {
    css: (inputContent, inputFile) =>
      postcss([require('postcss-import')])
        .process(inputContent, { from: inputFile })
        .then((result) => result.css),
  },
});

And just like before we can use the hashFileName in our templates:

<link rel="stylesheet" href="{{   "/assets/main.css" | hashFileName }}" />

If you are interested you can install the plugin using the following command:

npm install -D fec/eleventy-plugin-asset-pipeline

You can find more information about the project on Codeberg and NPM.