Buy

JavaScript Versioning and Cleanup

After a while, this versioning magic is going to clutter up our web/css directory. That's really no problem - our rev-manifest.json always updates to point to the right one. So one good solution to all this clutter is to ignore it! We don't need to perfect everything.

But since you're still listening, let's clean that up.

Grab an npm library called del to help us with this. So:

npm install del --save-dev

This is not a gulp plugin, so we need to go to the top and add var del = require('del'):

87 lines gulpfile.js
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var del = require('del');
... lines 4 - 87

This library does what it sounds like - it helps delete files.

We need a way to clean up our generated files. That sounds like a perfect opportunity to add a new task! Call it clean:

87 lines gulpfile.js
... lines 1 - 73
gulp.task('clean', function() {
... lines 75 - 78
});
... lines 80 - 87

Inside here, we want to remove everything that gulp generates. The first thing I can think of is the rev-manifest.json file. We don't need to clear this, but if you delete a CSS file, its last map value will still live here. So to keep only real files in this list, we might as well remove it entirely once in awhile.

To do that, use del.sync(). This means that our code will wait at this line until the file is actually deleted. The path to the manifest is further up. But hey, let's not duplicate! Instead, copy that path and reference a new config option called revManifestPath. Up top, I'll actually add that property to config:

87 lines gulpfile.js
... lines 1 - 4
var config = {
... lines 6 - 10
revManifestPath: 'app/Resources/assets/rev-manifest.json'
};
... lines 13 - 15
gulp.src(paths)
... lines 17 - 24
// write the rev-manifest.json file for gulp-rev
.pipe(plugins.rev.manifest(config.revManifestPath, {
merge: true
}))
... lines 29 - 87

Ok! Now just feed that to del.sync(). The other things we need to clean up are web/css/*, web/js/* and web/fonts/*:

87 lines gulpfile.js
... lines 1 - 73
gulp.task('clean', function() {
del.sync(config.revManifestPath);
del.sync('web/css/*');
del.sync('web/js/*');
del.sync('web/fonts/*');
});
... lines 80 - 87

Great! Now, we could run this manually, but instead of doing that, add this to the beginning of the default task. So when I run gulp, it'll start by cleaning things up.

87 lines gulpfile.js
... lines 1 - 85
gulp.task('default', ['clean', 'styles', 'scripts', 'fonts', 'watch']);

We have almost 10 things in web/css. Gulp, take out the trash.

gulp

My, what a tidy directory.

Versioning JavaScript

There's one more improvement we need to make. The bottom of every page reminds us that "Life finds a way". This message is added via JavaScript. And that code lives inside the one JS file: site.js. It deserves versioning too.

Go steal the plugins.rev() line from addStyle() and put that right before the sourcemaps of addScript. Woopsies, I must have gotten a little too excited with my indentation. Next, grab the last 2 lines that dump the one manifest file:

93 lines gulpfile.js
... lines 1 - 31
app.addScript = function(paths, outputFilename) {
gulp.src(paths)
... lines 34 - 37
.pipe(plugins.rev())
.pipe(plugins.if(config.sourceMaps, plugins.sourcemaps.write('.')))
.pipe(gulp.dest('web'))
// write the rev-manifest.json file for gulp-rev
.pipe(plugins.rev.manifest(config.revManifestPath, {
merge: true
}))
.pipe(gulp.dest('.'));
};
... lines 47 - 93

We also need to correct the paths so that the manifest has the js/ directory part in the filename. So, to concat(), I'll add js/, then put just web for the first dest() call:

93 lines gulpfile.js
... lines 1 - 31
app.addScript = function(paths, outputFilename) {
gulp.src(paths)
... lines 34 - 35
.pipe(plugins.concat('js/'+outputFilename))
... lines 37 - 39
.pipe(gulp.dest('web'))
... lines 41 - 45
};
... lines 47 - 93

Ok, restart gulp!

gulp

Now check out js/. Very good - we've got site- the hash. And open up rev-manifest.json - it's got one new entry for this. The setup for CSS and JS files is no different - the maps are all getting put into the same file.

If we refresh now, we of course don't see our message. We're still including site.js. But since we already made our Twig plugin, we can pipe that path through asset_version. And that'll take care of everything.

Where Now?

I really hope you now love Gulp as much as I do! There's more you can do, like using gulp-autoprefix to add the annoying vendor-specific CSS prefixes for you. This setup is something that works well for me, but go ahead and make it your own. If you're doing some cool things with Gulp, let us know in the comments.

Seeya next time!

Leave a comment!

  • 2016-05-18 weaverryan

    It's ok - you keep posting good questions and (often) good answers to your own questions :). I hope it'll help others!

    Cheers!

  • 2016-05-14 kaizoku

    Hi Ryan, is there a way to delete all file from a repository but one ?
    I did a clean-all task to clean the logs and the cache but I want to keep my .gitkeep file inside.
    Thx.

    Erf - sorry for the newbie question, I've just read the doc and found my answer ...

    del.sync('app/cache/*', '!app/cache/.gitkeep');