【问题标题】:How do you create an empty stream in Gulp?你如何在 Gulp 中创建一个空流?
【发布时间】:2014-09-01 12:04:17
【问题描述】:

SSCCE:

gulp.task('foo', [], function() {
    var barFiles = getBarFiles();
    var bazFiles = getBazFiles();

    var barStream, bazStream;
    if (barFiles && barFiles.length > 0) {
        barStream = gulp.src(barFiles);
    }
    if (bazStream && bazStream.length > 0) {
        bazStream = gulp.src(bazStream);
    }
    return eventStream
        .merge(barStream, bazStream)
        .pipe(g.concat('bar-and-baz'))
        .pipe(gulp.dest('./foo-output/'));
});

getBarFiles()getBazFiles() 可能返回一个空数组, gulp.src(): Error: Invalid glob argument 允许, 因此需要使用if 条件来包装流的创建。

所以问题是,我如何创建一个空流, 以便它可以与非空流上的另一个空合并?

【问题讨论】:

  • 您可以考虑使用gulp-util.noop 创建一个空流。
  • @Chris 所以,“一个除了直接传递数据什么都不做的流”,不需要gulp.src 来传递数据吗?
  • 这就是我理解它的行为方式。但是,我没有使用此方法的任何过期时间,因此您需要查看这是否回答了您的问题(这就是为什么我将其发布为评论,而不是作为答案)。

标签: javascript stream gulp


【解决方案1】:

如何使用:

return gulp.src('.');

对于较新的 Gulp,您可能需要添加 allowEmpty: true 选项,如下所示:

return gulp.src('.', {allowEmpty: true});

正如我认为它应该只传递流中的当前目录而不对其进行任何操作。对我有用。

【讨论】:

  • 没有 allowEmpty 不再工作:真正的参数
  • @loenix 所以添加参数并享受:)
【解决方案2】:

一个用于创建用于 gulp 的空流的函数(从 vinyl-fs 源代码中收集)是这样的:

var through2 = require('through2');

function createEmptyStream() {
    var pass = through2.obj();
    process.nextTick(pass.end.bind(pass));
    return pass;
}

如果你在例子中使 barFiles = createEmptyStream(),它的功能是一样的。

gulp (3.9.1)vinyl-fs (0.3.0) 的当前版本 2016-03-05 允许一个空的 src 数组(来自我的测试)。它使用类似于上面的东西来创建一个空流。您的示例在当前版本中有效(大部分是原样):

var eventStream = require('event-stream');
var gulp = require('gulp');
var g = require('gulp-load-plugins')();

function getBarFiles() {
    return [
    ];
}

function getBazFiles() {
    return [
        'baz.txt'
    ];
}

gulp.task('foo', [], function() {
    var barFiles = getBarFiles();
    var bazFiles = getBazFiles();
    var barStream = gulp.src(barFiles);
    var bazStream = gulp.src(bazFiles);

    return eventStream
        .merge(barStream, bazStream)
        .pipe(g.concat('bar-and-baz.txt'))
        .pipe(gulp.dest('./'));
});

gulp.task('default', [ 'foo' ]);

文件 bar-and-baz.txt 是这两个函数返回的 glob 中所有文件内容的串联。接受一个空的 glob 列表。

【讨论】:

  • 任何人都知道为什么他们用process.nextTick 异步调用流的end 方法,而不是在创建它之后直接调用它?因为从我对 gulp 任务的测试来看,同步版本似乎可以正常工作。
【解决方案3】:

也许我的回答太简单了,但我的问题与 OP 完全相同,我能够在不导入任何额外模块的情况下解决它:

if (platform != 'android') {
    // Android doesn't need anything here
    return gulp.src([]); // empty stream
}

换句话说,gulp.src() 不起作用,但 gulp.src([]) 似乎可以正常工作。还是我错过了什么?

编辑 2020 年 3 月 18 日:显然,Gulp 4.0 现在需要 allowEmpty 标志才能工作:

if (platform != 'android') {
    // Android doesn't need anything here
    return gulp.src([], {allowEmpty: true}); // empty stream
}

有关此问题,请参阅 Artur Stępień's answer,或 this related SO question

【讨论】:

  • @GrumpyCrouton 表面上看起来很相似,但事实并非如此。您提到的答案使用了一个附加模块“事件流”。我的答案仅使用 gulp 模块中已经存在的内容。对我来说,这是一个重要的区别。为什么我要引入一个不相关的模块来创建一些我已经可以在没有它的情况下制作的东西?
  • @GrumpyCrouton 至于它对问题的补充,我想说简化以前的答案绰绰有余。问题的年龄无关紧要; SO 问题旨在为未来的读者提供参考,而不仅仅是最初提出问题的人。
  • 这是一个重要的区别,我没有足够的经验来意识到这个区别(这就是我要求澄清的原因),因此,我很抱歉。将来,也许您应该指出您的代码与其他类似(甚至表面上相似)问题的差异,以避免与只是“尽其所能”进行审核的人混淆,因为答案看起来与其他人没有任何不同。谢谢你的澄清。在这种情况下,我相信你的答案超过了其他人,如果你说的是真的,这可能是迄今为止最好的答案。
  • 我已经修改了答案,使其更清楚一点,它不需要导入其他模块。感谢您提出好的建议,并感谢您做出适度的贡献以使 SO 变得更好。
  • 尝试这个我得到错误:无效的 glob 参数
【解决方案4】:

另一个很好地满足我需求的解决方案是使用gulp-tap

var config = require('./config');
var gulp = require('gulp');
var tap = require('gulp-tap');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

var noop = function() {};

gulp.task('mytask', function() {
  return gulp.src('*.js')
    .pipe(config.production ? uglify() : tap(noop))
    .pipe(concat('code.min.js'))
    .pipe(gulp.dest('dist'));
});

这使您可以轻松创建一个空流,您可以在 .pipe() 内部传递该流,因此您不必在外部有 if 语句。

注意:正如我刚刚发现的那样,您不应将 tap(noop) 存储到变量中并尝试在多个任务中使用它,因为这实际上可能会混合您的流并导致行为不稳定。

【讨论】:

    【解决方案5】:

    我用这个:

    https://github.com/dominictarr/event-stream

    es.merge([]);
    

    有效!

    【讨论】:

    • 感谢您的提示,我以同样的方式使用了merge2,效果也很好
    【解决方案6】:

    一种解决方案:

    gulp.task('foo', [], function() {
        var barFiles = getBarFiles();
        var bazFiles = getBazFiles();
    
        var barStream, bazStream;
        if (barFiles && barFiles.length > 0) {
            barStream = gulp.src(barFiles);
        }
        if (bazStream && bazStream.length > 0) {
            bazStream = gulp.src(bazStream);
        }
        var mergedStream;
        if (barStream && bazStream) {
            mergedStream = eventStream
                .merge(barStream, bazStream);
        }
        else if (barStream || bazStream) {
            mergedStream = barStream || bazStream;
        }
        if (mergedStream) {
            return mergedStream
                .pipe(g.concat('bar-and-baz'))
                .pipe(gulp.dest('./foo-output/'));
        }
    });
    

    通过测试每个流并仅在两者都存在时合并它们,从而避免了创建空流的需要。

    但是,我仍然想知道一种在 gulp 中创建空流的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      相关资源
      最近更新 更多