It is highly recommended to write plugins supporting streams. Here is some information on creating a gulp plugin that supports streams.
Make sure to follow the best practices regarding error handling and add a line that makes the gulp plugin re-emit the first error caught during the transformation of the content.
Writing a Plugin > Writing stream based plugins
Let's implement a plugin prepending some text to files. This plugin supports all possible forms of file.contents
.
var through = require('through2');
var PluginError = require('plugin-error');
// consts
const PLUGIN_NAME = 'gulp-prefixer';
function prefixStream(prefixText) {
var stream = through();
stream.write(prefixText);
return stream;
}
// plugin level function (dealing with files)
function gulpPrefixer(prefixText) {
if (!prefixText) {
throw new PluginError(PLUGIN_NAME, 'Missing prefix text!');
}
prefixText = new Buffer(prefixText); // allocate ahead of time
// creating a stream through which each file will pass
var stream = through.obj(function(file, enc, cb) {
if (file.isBuffer()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Buffers not supported!'));
return cb();
}
if (file.isStream()) {
// define the streamer that will transform the content
var streamer = prefixStream(prefixText);
// catch errors from the streamer and emit a gulp plugin error
streamer.on('error', this.emit.bind(this, 'error'));
// start the transformation
file.contents = file.contents.pipe(streamer);
}
// make sure the file goes through the next gulp plugin
this.push(file);
// tell the stream engine that we are done with this file
cb();
});
// returning the file stream
return stream;
}
// exporting the plugin main function
module.exports = gulpPrefixer;
The above plugin can be used like this:
var gulp = require('gulp');
var gulpPrefixer = require('gulp-prefixer');
gulp.src('files/**/*.js', { buffer: false })
.pipe(gulpPrefixer('prepended string'))
.pipe(gulp.dest('modified-files'));