Gulp, an easier to swallow workflow

It is truly amazing how a well tweaked development environment can boost your productivity as well as your enjoyment when coding. There are so many tools available to us today, and so many ways to customize them... you can either find yourself lost in choice or lost in details. Here I'll try to detail the jumping off point of one of the tools in my chain.

Grunt

I was a long time user of Grunt. I love the logo (the sticker looks great on my laptop, and we all know that is the primary reason one should consider a tool), we used it at work, and since it was one of the first new choices on the scene, it had an early start for those of us itching for change. Slowly I started to hear more and more about Gulp.

Gulp

While we never did switch to Gulp for our build process where I worked (disclaimer: I've since left that company, they very well may have switched now) I did see more and more people begin to adopt it. People coming in for interviews would be using Gulp instead of Grunt, and standing by it.

There's been a great many things written comparing the two, I won't be repeating the brilliant thoughts others have already expressed.

My Setup

My intent for this post is just to detail for myself mostly the setup of my Gulp file, to remind myself later of the choices I made.

Depending on the project I'm working on, the file will get tweaked and added to... this is just the commonest pieces that I'm likely to use for most all projects. When working on an Angular project, for example, I'll include more Angular plugins (ng-annotate, for example). When working with React I'll include more plugins to aid with React (gulp-react would be a choice there).

CSS

I've come to be a SASS convert (SCSS more specifically, but I think most people that say SASS really mean SCSS, except for those that don't). Yeah, at work we were a LESS shop, but this post isn't about CSS :)
For compiling my SCSS into CSS I've chosen to use gulp-sass. My reaons are out-dated, but at the time the gulp-ruby-sass pluging had a couple of issues with inline source maps, more about that here if you're really interested.

I also use the gulp-autoprefixer plugin. Since this can easily be done via a gulp plugin it means I don't have to maintain my own sass mixins to accomplish the same.

And finally gulp-sourcemaps for those inline source maps.

Javascript

I like to lint my Javascript with gulp-jshint. Not much more to say about that here.

Images

I've set up to auto-optimize the images I use, which saves me from needing to use ImagOptim on the Mac, or another solution. The plugins for this are:

  • imagemin-jpegoptim
  • imagemin-optipng
  • imagemin-pngquant
  • imagemin-svgo

In Use

That's enough of the laundry list. The plugins you choose are likely going to be different than mine, more than mine, less than mine. The effort I made for me was to find a common set that I'd likely be using over and over to build a skeleton gulpfile with.

Errors

I hated that my long running gulp process would fail when I had an error that crashed one of the plugins. I'm sure there are a multitiude of solutions for this, but I ended up using gulp-plumber.

var onError = function(err) {
  gutil.beep();
  console.log(err);
  this.emit('end');
};

.pipe(plumber({errorHandler: onError}))

That bit of piping to plumber is reused all over the place in my gulpfile. Growl even gives me a little heads up notification that my build failed.

Source

The final thing I want to talk about is defining my source files, both incoming and outgoing. I do this up at the top of the gruntfile in two objects.

var input  = {
  'html': 'source/*.html',
  'sass': 'source/scss/**/*.scss',
  'javascript': 'source/javascript/**/*.js',
  'vendorjs': 'dist/assets/javascript/vendor/**/*.js',
  'images': 'source/images/**/*.{png,jpg,jpeg,gif,svg}'
};
 
var output = {
  'html': 'dist',
  'stylesheets': 'dist/assets/stylesheets',
  'javascript': 'dist/assets/javascript',
  'images': 'dist/assets/images'
};

For me, it keeps things neat and tidy and it's easy for me to make any changes as needed on a project-to-project basis.

Running

I guess the final thing to mention is the use of gulp-livereload. I absolutely love LiveReload and feel at a disadvantage when I don't use it.

Wrap up

My entire gulpfile is available at this gist if you want to take a closer look or even maybe use it as the starting point for your own gulp skeleton.

Again, remember that this is a skeleton setup. It's meant to be tweaked and manipulated based on the project. I primarily use it as a quick starting point for playing around with new frameworks and libraries. For a production build process you'd want to be sure to add a test runner, minifiers, etc.