gulp-foreach 不遍历所有文件

gulp-foreach not looping over all files

我有一个非常基本的 gulp-foreach 用法,它失败得很厉害,我想我一定是做错了什么;我只是(现在)尝试打印在 gulp.src 中找到的所有文件。当使用 gulp-foreach 执行此操作时,只会打印非常非常小的文件样本——大约数百个文件中的 15 个。当使用 gulp-print 时,一切正常。

const gulp = require('gulp'),
      foreach = require('gulp-foreach'),
      gulpPrint = require('gulp-print');

gulp.src([`../../**/*.js`].concat([]))
    .pipe(gulpPrint(path => {
        console.log(path);
    }))
    .pipe(foreach((stream, file) => {
        console.log(file.path);
        return stream;
    }))

带有 foreach 的代码被触发了大约 15 次,与 gulpPrint 交织在一起,随后是大量 gulpPrint 语句。如果我注释掉 gulpPrint 部分,foreach 打印大约 15 次然后退出,并且 gulpPrint 单独,正如预期的那样,用找到的每个文件淹没控制台。

我只能使用 gulp-print,但我想知道我在使用 gulp-foreach 时做错了什么。

首先:gulp-foreach 并不是真正适合您的用例的插件。

gulp-foreach 允许您为每个文件创建一个子流并将子流的结果发送到原始流中。这意味着您可以为每个输入文件发出多个文件(see this example). In this regard it is very similar to the higher-order function flatmap in functional programming. Which is why the author of gulp-foreach has recently renamed gulp-flatmap 的插件。

您感兴趣的只是访问流中的每个文件并打印其路径,这就是 higher-order function map. The right plugins for this are map-stream or gulp-tap (which is what the author of gulp-foreach used to recommend) 的情况。

现在回答你的实际问题。

如前所述,gulp-foreach 将创建的子流中的所有文件发送到原始流。但是,您没有对写入原始流的文件执行任何操作。 Node.js 默认情况下,对象流的 highWaterMark 为 16,因此一旦 gulp-foreach 将 16 个文件写入原始流,缓冲区已满并且 gulp-foreach 块。

为了解决这个问题,您需要使用 gulp-foreach 写入流的文件。您可以为此简单地使用虚拟 .on('data') 处理程序:

gulp.src([`../../**/*.js`].concat([]))
  .pipe(gulpPrint(path => {
    console.log(path);
  }))
  .pipe(foreach((stream, file) => {
    console.log(file.path);
    return stream;
  }))
  .on('data', (data) => { });

然而,在 gulp 中执行此操作的通常方法是让 gulp 使用流,而不是简单地从创建它的任务中返回流:

gulp.task('default', function() {
  return gulp.src([`../../**/*.js`].concat([]))
    .pipe(gulpPrint(path => {
       console.log(path);
    }))
    .pipe(foreach((stream, file) => {
       console.log(file.path);
       return stream;
    }));
});

之所以看不到所有文件,是因为您没有return承诺,并且任务在遍历所有文件之前完成

return gulp.src 像这样:

const gulp = require('gulp'),
  foreac**strong text**h = require('gulp-foreach'),
  gulpPrint = require('gulp-print');

gulp.task('default', function () {
return gulp.src([`../../**/*.js`].concat([]))
    .pipe(gulpPrint(path => {
        console.log(path);
    }))
    .pipe(foreach((stream, file) => {
        console.log(file.path);
        return stream;
    }))

})