Плагин gulp - wrap (который использует through2) вывод со строкой
Я хотел бы знать, как именно я могу манипулировать выводом моего плагина Gulp, так что, например, независимо от того, сколько файлов передано плагину, он обернет вывод строкой. В настоящее время я не могу знать, когда будет сделан последний файл.
Упрощенный пример ниже будет повторять 3 файла и создаст новый файл с именем output.js
и в нем будет трижды строка xxx
(XXXXXXXXX).
Я хотел бы, чтобы сам плагин обернул содержимое, чтобы вывод был: +xxxxxxxxx+
,
Как я могу это сделать? Спасибо!
Gulpfile
var gulp = require('gulp');
var concat = require('gulp-concat');
var foo = require('./index');
gulp.task('default', function() {
gulp.src([a.html, b.html, c.html])
.pipe(foo())
.pipe(concat('output.js'))
.pipe(gulp.dest('./test/output'))
});
Самый основной плагин gulp (index.js):
var through2 = require('through2'),
gutil = require('gulp-util');
var PLUGIN_NAME = 'foo';
module.exports = function( options ){
// through2.obj(fn) is a convenience wrapper around
// through2({ objectMode: true }, fn)
return through2.obj(function( file, enc, callback ){
file.contents = new Buffer( 'xxx' );
this.push(file);
callback();
});
}
Я понимаю, что файлы в настоящее время просто возвращаются измененными, но я не понимаю, как добавить текст и вернуть объединенный результат, который мне нужен, сохраняя при этом все в порядке с рабочими стандартами Gulp.
"Настоящий" плагин должен на самом деле обернуть результаты файлов:
var foo = { FILES_CONTENT }
где FILES_CONTENT
фактически будет объединенной строкой всех файлов:
"file_name" : "file_content",
"file_name" : "file_content",
...
2 ответа
Я бы сделал следующие изменения в вашем gulpfile.js:
var gulp = require('gulp');
var foo = require('./index.js');
gulp.task('default', function() {
return gulp.src(['a.html', 'b.html', 'c.html'])
.pipe(foo({fileName:'output.js', varName:'bar'}))
.pipe(gulp.dest('./test/output'))
});
Так как ваш foo()
сам плагин объединит все файлы, нет необходимости использовать gulp-concat
совсем. Вместо этого ваш плагин должен принять опцию fileName
это обеспечивает имя сгенерированного файла. Я также добавил еще один вариант varName
который предоставит название var
в выходном файле.
Я предполагаю, что a.html, b.html и c.html являются простыми файлами HTML, примерно так:
<h1 class="header">a</h1>
Как вы уже поняли, вам нужно объединить все файлы в самом плагине. Это не очень сложно, однако и не требует много кода. Вот index.js, который делает именно это:
var through2 = require('through2'),
gutil = require('gulp-util'),
path = require('path'),
File = require('vinyl');
var PLUGIN_NAME = 'foo';
module.exports = function(options) {
var files = { };
var outputFile = null;
return through2.obj(function(file, enc, callback){
outputFile = outputFile || file;
var filePath = path.relative(file.base, file.path);
files[filePath] = file.contents.toString();
callback();
}, function(callback) {
outputFile = outputFile ? outputFile.clone() : new File();
outputFile.path = path.resolve(outputFile.base, options.fileName);
outputFile.contents = new Buffer(
'var ' + options.varName + ' = ' +
JSON.stringify(files, null, 2) + ';'
);
this.push(outputFile);
callback();
});
}
Так как вы хотите вывести отображение ключа / значения из имен файлов на содержимое файла, наш transformFunction
просто хранит обе эти вещи в обычном объекте JavaScript files
, Ни один из самих входных файлов не генерируется. Их имена и содержимое просто хранятся до тех пор, пока мы не получим их все.
Единственная сложность - убедиться, что мы уважаем .base
свойство каждого файла, как обычно для плагинов gulp. Это позволяет пользователю предоставлять пользовательскую базовую папку, используя base
вариант в gulp.src()
,
После того, как все файлы были обработаны through2
вызывает flushFunction
, Там мы создаем наш выходной файл с предоставленным fileName
(еще раз убедившись, что мы уважаем .base
имущество).
Создание содержимого выходного файла - это всего лишь вопрос сериализации нашего files
использование объекта JSON.stringify()
(который автоматически заботится о любом побеге, который должен быть сделан).
В результате ./test/output/output.js будет выглядеть следующим образом:
var bar = {
"a.html": "<h1 class=\"header\">a</h1>\n",
"b.html": "<h1 class=\"header\">b</h1>\n",
"c.html": "<h1 class=\"header\">c</h1>\n"
};
Вы должны использовать технику Gulp Pipeline (стандарт). Это означает, что вы можете использовать пакет gulp-insert для добавления строки xxx.
var insert = require('gulp-insert');
.pipe(insert.append('xxx')); // Appends 'xxx' to the contents of every file
Вы также можете добавлять, дополнять и переносить этот пакет, и он, конечно, поддерживает стандарты gulp.
Итак, полный пример будет:
var gulp = require('gulp');
var concat = require('gulp-concat');
var foo = require('./index');
var insert = require('gulp-insert');
gulp.task('default', function() {
gulp.src([a.html, b.html, c.html])
.pipe(foo()
.pipe(insert.append('xxx'))
.pipe(concat('output.js'))
.pipe(gulp.dest('./test/output'))
});