Raine Revere
Raine Revere

Reputation: 33627

How do I write a gulp plugin that uses other gulp plugins?

I have a gulp task for precompiling handlebars templates that consists of the following:

gulp.src(['templates/*.hbs'])
    .pipe(handlebars())
    .pipe(declare({
      namespace: 'Template.templates',
      noRedeclare: true
    }))
    .pipe(concat('compiled.js'))
    .pipe(header('Template = {};\nTemplate.render = function(templateName, context) { return Handlebars.template(Template.templates[templateName])(context) };\n'))
    .pipe(gulp.dest('templates'));

I want to create a gulp plugin that wraps this functionality to make it easier to use, like this:

gulp.src(['templates/*.hbs'])
  .pipe(handlebars2())
  .dest('templates')

Or with options:

gulp.src(['templates/*.hbs'])
  .pipe(handlebars2({
    filename: 'compiled.js',
    namespace: 'Template'
  }))
  .dest('templates')

The documentation for writing gulp plugins and the examples source code I've looked at only show the usage of streams, and I'm not sure how to apply that to leveraging other gulp plugins inside my own.

How do I write a gulp plugin to accomplish the functionality of handlebars2 above?

Even if someone just points me in the right direction, I can solve it and post the solution as an answer for others. Thanks!

Upvotes: 4

Views: 747

Answers (2)

Raine Revere
Raine Revere

Reputation: 33627

Since gulp plugins just process streams, you can use stream-combiner:

var combine = require('stream-combiner');

function coffeePipe() {
    return combine(
        coffeescript(),
        coffeelint.reporter('fail').on('error', function(){
            gutil.beep();
            gulp.run('lint');
        });
};

//usage:
gulp.src().pipe(coffeePipe());

https://github.com/OverZealous/lazypipe/issues/4#issuecomment-36785601

I found this comment from the author of lazypipe revealing:

Honestly, when I created lazypipe, I wish I had just thought of this latter solution. It's really the same thing, only slightly more verbose, and solves the same issue. lazypipe is pretty popular, though, so I'm glad it's being used!

Upvotes: 1

Walter Macambira
Walter Macambira

Reputation: 2605

What a gulp plugin does is to return a stream, which will consume data from another stream:

readable.pipe(writable);

As you are trying to make a gulp plugin, you don't have access directly to the stream you are reading from. You can only access the data it passes to you (the vinyl files, for example).

This way you cannot pipe to it in a conventional way. What you are trying to do is to reuse a partial pipeline.

To achive such thing easily, try using lazypipe:

var lazypipe = require('');

var handlebars2 = lazypipe()  
    .pipe(handlebars)
    .pipe(declare,{
      namespace: 'Template.templates',
      noRedeclare: true
    })
    .pipe(concat,'compiled.js')
    .pipe(header,'Template = {};\nTemplate.render = function(templateName, context) { return Handlebars.template(Template.templates[templateName])(context) };\n');

Remember not to call stream creation functions here, lazypipe will call them for you.

Hope I've helped.

Upvotes: 1

Related Questions