1

我想知道如何准确地操作我的 Gulp 插件的输出,例如,无论有多少文件传递给插件,它都会用字符串包装输出。目前我不知道最后一个文件何时完成。

下面的超级简化示例将迭代 3 个文件,并将创建一个名为的新文件output.js,其中将包含三倍的字符串xxx(xxxxxxxxx)。

我希望插件本身包装内容,因此输出将是:+xxxxxxxxx+.

我该怎么做?谢谢!

吞吐文件

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 }

whereFILES_CONTENT实际上是所有文件的串联字符串:

"file_name" : "file_content",
"file_name" : "file_content",
...
4

2 回答 2

3

我将对您的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.htmlb.htmlc.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"
};
于 2016-12-28T17:27:34.133 回答
0

您应该使用 gulp 管道技术(标准)。这意味着您可以使用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'))
});
于 2016-12-26T06:08:28.670 回答