Streams in Wiredep

wiredep is a neat little Node package that does one pretty awesome thing: it automatically wires up your Bower components to your HTML/(S)CSS based on dependencies (i.e. it automatically includes them in the correct order!).

You may not have heard of wiredep before, but it's likely you've used it if you've used the grunt-wiredep (formally grunt-bower-install) Grunt plugin which is a popular one that uses it, and was a precursor to wiredep.

Both the Node package and the Grunt plugin were built by Stephen Sawchuk, a friendly, talented developer from Michighan. I don't know very much about him, even though he has added me to the team that manages wiredep. He works on the Yeoman team and built grunt-wiredep for use in the awesome build systems that come with many Yeoman generators, and eventually extracted the parts out to create what is now known as wiredep and modified the original Grunt plugin to be a wrapper around wiredep.

Anyway, introduction done. On to the meat of the article:

Wiredep, Streams and Gulp, oh my!

I've been talking about streams a little bit lately and how it relates to Gulp. Well, streams can be pretty cool, and are a fundamental part of how Gulp works.

You might ask yourself, "Why isn't there a gulp-wiredep pulgin?" Before I answer, I'd liket to remind you of one of Gulp's tenents, taken from their website:

By preferring code over configuration, gulp keeps simple things simple and makes complex tasks manageable.

In other words: why create a dedicated gulp-wiredep plugin when you can just use wiredep directly in your Gulp build? Indeed, you can just use wiredep straight up in your Gulp build in its own task. But once you try to do more complex things, you may run into some issues in not being able to fully integrate wiredep with the other streams from Gulp.

That is, until you realize that wiredep supports streams! It wasn't documented until only recently (in part, thanks to my efforts, I might add ;-)), but I was digging into the source code of wiredep, trying to figure out something else, and I noticed that it had some code related to streams. I dug a little deeper, and indeed, wiredep has stream support for perfect integration with Gulp (and anything else that would use a stream).

For example, I had been using wiredep without streams like this:

/////////////////////
// Without Streams //
/////////////////////

var gulp    = require('gulp');  
var wiredep = require('wiredep');

gulp.task('bower', function () {  
  wiredep({
    src: './src/footer.html',
    directory: './bower_componets/',
    bowerJson: require('./bower.json'),
  });
});

which was all well and good until I needed another task that depended on the bower task from being completed. The simplest way to do that was to return a stream. Well, good thing wiredep support streams! Change the above code to this and then we're all good:

//////////////////
// With Streams //
//////////////////

var gulp    = require('gulp');  
// note that we're grabbing the stream function
var wiredep = require('wiredep').stream;

gulp.task('bower', function () {  
  gulp.src('./src/footer.html')
    .pipe(wiredep({
      directory: './bower_componets/',
      bowerJson: require('./bower.json'),
    }))
    .pipe(gulp.dest('./dest'));
});

BAM, just like that, we have full Gulp integration!

Conclusion

As many of you that have been getting into Gulp more have noticed, the solution for a lot of your Gulp needs aren't always a Gulp specific plugin. That's one of the cool things about Gulp: it's just code.

wiredep is one of those tools that has everything you need out of the box and there's no need for a Gulp specific plugin. Employ some of the techniques in this post and you too can benefit from the Wiredep magic of simple, auto-linking, Bower dependency management.