简体   繁体   中英

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!

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM