Here's an answer that works in 2019.
Plugin:
var Vinyl = require('vinyl');
var through = require('through2');
var path = require('path');
// https://github.com/gulpjs/gulp/tree/master/docs/writing-a-plugin#modifying-file-content
function stringSrc(filename, string) {
/**
* @this {Transform}
*/
var transform = function(file, encoding, callback) {
if (path.basename(file.relative) === 'package.json') {
file.contents = Buffer.from(
JSON.stringify({
name: 'modified-package',
version: '1.0.0',
}),
);
}
// if you want to create multiple files, use this.push and provide empty callback() call instead
// this.push(file);
// callback();
callback(null, file);
};
return through.obj(transform);
}
And in your gulp pipeline:
gulp.src([
...
])
.pipe(stringSrc('version.json', '123'))
.pipe(gulp.dest(destinationPath))
From source: https://github.com/gulpjs/gulp/tree/master/docs/writing-a-plugin#modifying-file-content
The function parameter that you pass to through.obj() is a _transform
function which will operate on the input file. You may also provide an
optional _flush function if you need to emit a bit more data at the
end of the stream.
From within your transform function call this.push(file) 0 or more
times to pass along transformed/cloned files. You don't need to call
this.push(file) if you provide all output to the callback() function.
Call the callback function only when the current file (stream/buffer)
is completely consumed. If an error is encountered, pass it as the
first argument to the callback, otherwise set it to null. If you have
passed all output data to this.push() you can omit the second argument
to the callback.
Generally, a gulp plugin would update file.contents and then choose to
either:
call callback(null, file) or make one call to this.push(file)