Solving Browser Cache Hell With Gulp-Rev

Even if you control cache policy with server proxy, sometimes the only way you can guarantee that the client is caching your served files correctly is by changing it’s filenames… on every deploy.

This is called file revision, and here I’ll explain how to easily automate it with gulp.

“Everything is gonna be alright”, Dog says. Let’s just trust him for now.

The Problem

  1. Our costumer was unhappy because she couldn’t see the app changes
  2. We discovered that our costumer’s company were using an internal proxy which were ignoring our cache policies headers and storing our older version’s files ([*.js, *.html, *.css, *.svg]) of our app… forever

The Solution: Concept

After doing this, we update every reference for these newly-hashed files inside our app files and… voilá!

Our costumer browser won’t ever have the same hashed-file cached unless it is, in fact, the latest version being served.

We call it file revision.

The App: Quick Background

The Solution: Implementation

  • gulp, for automating our task
  • gulp-rev, for renaming our files with random hashes. In this example, imported as rev
  • gulp-rev-collector, for switching non-hashed references by hashed-references inside our files. In this example, imported as collect
  • rev-del, for deleting non-hashed files in our /dist folder. In this example, imported as revDel

Step 1: creating our revision:rename gulp task

  • Get every compiled html, css, js and image file from our /dist folder
  • Generate & concatenate a hash on it’s name
  • Delete the previously compiled, unhashed file
  • Put the hashed file in the same place of it’s original, unhashed file
  • Generate a manifest.json (whose will be used in our next gulp task) that maps unhashed -> hashed filenames and put it in our /dist folder
gulp.task(“revision:rename”, [“compile”], () =>
.pipe(rev.manifest({ path: “manifest.json” }))

A closer look to our manifest.json:

xpto.html: xpto-293820djdx.html,
charming.css: charming-ds9udjvci.css,
carreta-furacao.js: carreta-furacao-dijds9xc9.min.js,
anything.svg: anything-f9efdx8cv.svg

Step 2: creating our revision:updateReferences gulp task

  • Point the path to our previously-generated manifest.json and a wildcard of files to look for unhashed references
  • Pass it to collect, which is expecting as a first parameter the path to a manifest.json and the following as paths of files to look inside
  • Rewrite every reference for every key of manifest.json to it’s respective value inside every html/json/css/js file (i.e: <link href=”charming.css”> would become <link href=”charming-ds9udjvci.css”>)
gulp.task(“revision:updateReferences”, [“compile”, “revision:rename”], () =>

Step 3: creating our compile:production gulp task

  • Depend on our actual compile task our front-end source files to the dist folder
  • Also depend on our newly created revision:rename & revision:updateReferences tasks
  • Be run just* in your CI tool’s deploy pipeline
gulp.task(“compile:production”, [“compile”, “revision:rename”, “revision:updateReferences”]);

*Because you don’t want to (and don’t need to) do file revision while coding locally, since it will take up more compilation time everytime a watched file is changed/compiled, decreasing your compiling performance.

There’s a whole lot more about web cache…

I’d be happy to help & answer any questions on this subject. Just hit ‘reply’ if you need!

This post was written in Sorocaba, Brazil

Busco ser Desenvolvedor, busco ser Criativo, busco Ser Humano.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store