I want to cache bust background images in my CSS. So if my original style is:
.one {
background: url(image.png);
}
A string can be added:
.one {
background: url(image.png?1234);
}
Or the file name could be changed:
.one {
background: url(image-1234.png);
}
Rather than using a random generator or a timestamp id like to use a hash of the image file so that the cache is only busted when needed (when the file has actually changed).
Im using SASS and Gulp so I could use Gulp Cache Buster and Gulp Hasher:
https://github.com/disintegrator/gulp-hasher
https://github.com/disintegrator/gulp-cache-buster
The issue I have with these is that it looks like you need to modify your SASS. So if you start with this:
.logo {
background: url(assets/images/logo.svg);
}
You need to change it to this:
.logo {
background: url(ASSET{assets/images/logo.svg});
}
I want to keep my SASS nice and clean and not modify it in this way. Is this possible?
The way I see it you have two options - both of which would use the hasher and cache busting plugins you listed:
Write a gulp task that would automatically add ASSET{ ... }
around all of the URLs in your CSS file. This would happen after concatenation and before hashing/busting. Since you have a bounty on this question, let me know if you would like me to write that task. I suggest you take a stab at it though b/c you might learn some neat things.
Ideal solution: The cache busting plugin has an option for defining the regex to use to find assets. By default, the regex is set to /ASSET{(.*?)}/g
, but you could easily update to something to match good ol' vanilla CSS url(...)
s. Again, since you have a bounty let me know if you want help on the regex - but I suggest you take a stab at it b/c you might learn something neat (pssst, you want to ignore data:
URLs).
Try this regex in the cache bust config: /url\((?!['"]?data:)['"]?([^'"\)]*)['"]?\)/g
If you want to ignore URLs which start with "http" (meaning they're hosted on another domain), then use the following regex. This assumes that all paths to your assets are relative, which they should be: /url\((?!['"]?(?:data|http):)['"]?([^'"\)]*)['"]?\)/g
http://www.regexpal.com/?fam=94251
If you want to be able to define the CSS attributes which will have hashed/busted URLs, you can use the following, which will only apply to URLs defined in background
, background-image
, and list-style
CSS attributes. You can add more by adding a pipe |
plus the name of the attribute after |list-style
: /(?:background(?:-image)?|list-style)[\s]*:[^\r\n;]*url\((?!['"]?(?:data|http):)['"]?([^'"\)]*)/g
http://www.regexpal.com/?fam=94252
You can use gulp-rev-all. It will be able to add hash to the files and rewrite them without the need to add any extra markup to your SASS file.
A very basic gulp file for the same would look like -
var gulp = require('gulp');
var sass = require('gulp-sass');
var RevAll = require('gulp-rev-all');
gulp.task('default', function () {
var revAll = new RevAll({dontRenameFile: ['index.html']});
gulp.src(['app.sass'])
.pipe(sass().on('error', sass.logError))
.pipe(revAll.revision())
.pipe(gulp.dest('build'));
gulp.src(['**.jpg','**.png','**.gif'])
.pipe(revAll.revision());
return gulp.src('index.html')
.pipe(revAll.revision())
.pipe(gulp.dest('build'));
});
Note: Used dontRenameFile option to exclude the html file from being revisioned
I have created a working example at https://github.com/pra85/gulp-sass-filerev
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With