Adding sourcemaps for debugging in Gulp

It’s been a while since I’ve written about my web development workflow and whilst I have been distracted by WordPress and Cloudflare a lot recently, it’s still something that always draws me back.  I love using Gulp to automate steps of the build process, enabling me to quickly and easily produce a well optimised and efficient website.

I’ve previously covered minifying (or uglifying) javascript and adding stylesheets into the mix as well, and whilst having beautifully compressed static assets makes for very efficient download and load times, it doesn’t half make it difficult for the developer to see what’s going on when something needs debugging.

The answer to this is sourcemaps.  These are files which map the optimised file back to the original file, and we can use Gulp to automatically generate them for us.  These maps files aren’t downloaded by the browser unless you’ve got the Developer Tools open, in which case it will download the file in order to try and restore the files back to their pre-optimised state.

The first thing that we need to do is install the gulp-sourcemaps plugin using NPM…

npm install --save-dev gulp-sourcemaps

Then (if you’re not automatically requiring plugins) you need to require it at the top of your “gulpfile.js” file…

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

Now if we take a look at at javascript sample task from previous posts we should have something like this…

var js = function() {
  return gulp.src(["js/*.js"])
    .pipe(concat("script.js"))
    .pipe(uglify())
    .pipe(optimize())
    .pipe(gulp.dest("build/js"));
};

Now we want to wrap all the file changes so that they can be included in the map file, like this…

var js = function() {
  return gulp.src(["js/*.js"])
    .pipe(sourcemaps.init())
    .pipe(concat("script.js"))
    .pipe(uglify())
    .pipe(optimize())
    .pipe(sourcemaps.write("../maps"))
    .pipe(gulp.dest("build/js"));
};

As you can see the first thing we do after loading the source files is to call init() in order to initialise the map file.  Then the last thing that we do before outputting the final javascript file is to call write() to output the map file(s) into a maps folder – this is with a path relative to the final destination path.

You can call write() without specifying a path, in which case the map details get written into the final javascript file in a comment, but this isn’t very efficient as it bloats the file, so I would always recommend using external map files.  This just outputs a single line comment in the final javascript file, like this…

//# sourceMappingURL=../maps/script.js.map

This is what tells the browser’s Developer Tools that there’s a map file available to download.

However, it should be noted that all of the plugins that we call between init() and write() need to support sourcemaps for this to fully work.  All of the ones I have used do, but it’s worth checking and testing to make sure that it’s working.  There’s a list on the Github page of plugins that work.

And we can use exactly the same process for stylesheets as well, don’t forget.