Minifying (or uglifying) javascript

Totally in keeping with my New Year’s Resolution, here is a lovely new blog post!  And it’s a continuation of my new development process.  The last post in the series detailed my switch to using pump instead of pipe in my Gulp task.

Today’s post is about minifying javascript, which is sometimes called “uglifying”.  The reason being that this beautifully crafted javascript snippet…

//jquery wrapped anonymous function
  $(function() {
    //clickjacking protection
    if(self!==top) {
      top.location = self.location; //break out of frame
    }
  });

…gets minified to this monstrosity…

$(function(){self!==top&&(top.location=self.location)});

As you can see, the comments and whitespace have all been stripped, as well as converting the if statement to the shorthand variant – a number of operations are performed as part of this process.

So why on earth would we want to do this, I hear you cry.  Well essentially because it makes the file size smaller (in some cases, considerably smaller).  In the example above, the character count has gone from 166 to 56, which is approximately a third of the size, but with exactly the same functionality.  This makes it both quicker and cheaper (if you’re on any kind of data plan, such as a mobile phone) to download the file for the user, and also saves you bandwidth costs.  This can be better than gzip compression for some files, but even better yet, do both!

If you want to read further on why you should do this, you can read this blog post relating to Drupal.

The best way to achieve this is to use the gulp-uglify package. So I installed this plugin and then included it at the top of my Gulp file…

var uglify = require("gulp-uglify");

I then took the task that I wrote about in my last blog post in this series and added the highlighted line…

gulp.task("js",function(cb) {
  pump([
    browserify(jsFiles).bundle(),
    source("script.js"),
    uglify(),
    gulp.dest("build/js")
  ],cb);
});

This doesn’t actually work, so not quite that simple.  The problem is to do with the way that Gulp can handle files as streams or buffers.  In this case the browserify plugin outputs the files as streams, but the gulp-uglify package requires them as buffers.

Luckily this is easily fixed using a plugin called vinyl-buffer, which once included like so…

var buffer = require("vinyl-buffer");

…can be added to the task so that it looks like this…

gulp.task("js",function(cb) {
  pump([
    browserify(jsFiles).bundle(),
    source("script.js"),
    buffer(),
    uglify(),
    gulp.dest("build/js")
  ],cb); 
});

Now we have a process which minifies our files, improving the performance and user experience, as well as reducing bandwidth costs – win win!

This is also covered in my Skillshare course, Optimising your website: A development workflow with Git and Gulp.  The relevant video is 11 – Minifying Javascript Files.