Плагин 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'))
});
Другие вопросы по тегам