Martynas Bardauskas

Martynas Bardauskas

Automated cache busting with Gulp

You probably want most of your image and other resources to be cached, so the users would have fast page loads with each page reload. Cache is great until there’s a need to update the website. Busting cache allows to have cached resources and painless updates.

There are ways to bust cache. Some use filename revving, some rely on query string for filenames. Some leave it to their CMS and others don’t think about it at all. I’ll cover only filename revving since it seems to be most effective.

Configuring web server

The easy part is configuring your apache web server through .htaccess:

1
2
3
4
5
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(bmp|css|cur|gif|ico|jpe?g|js|png|svgz?|webp|webmanifest)$ $1.$3 [L]
</IfModule>

Or the same thing with IIS web.config:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite Rule" stopProcessing="true">
<match url="^(.+)\.(\d+)\.(bmp|css|cur|gif|ico|jpe?g|js|png|svgz?|webp|webmanifest)$" ignoreCase="true" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="true" negate="true" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:3}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Renaming files with gulp build step

There are ways to implement this into the build step. Usually we incorporate it with bundling tasks (eg. requirejs and gulp-cssmin). The following is the most trivial task to handle filename revving with Gulp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// gulpfile.js
var gulp = require('gulp');
var rename = require('gulp-rename');
var moment = require('moment');

var cache_suffix = moment().format('X');

gulp.task('bust-cache', function() {
gulp.src(['./temp/bundle.css', './temp/bundle.js'], {base: './temp'})
.pipe(rename({
suffix: '.' + cache_suffix
}))
.pipe(gulp.dest('./dist'))
});

gulp.task('default', ['bust-cache'], function() {});

Note that this can be easily achieved with Grunt cache busting tool or any other task runner. Gulp also has full plugins to bust cache, though sometimes you end up with something completely custom just because you can.