gulp-foreach不会循环遍历所有文件

时间:2016-08-09 16:00:42

标签: javascript node.js gulp gulp-print

我对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做错了什么。

2 个答案:

答案 0 :(得分:2)

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

gulp-foreach允许您为每个文件创建一个子流,并将子流的结果发送到原始流中。这意味着您可以为每个输入文件(see this example)发出多个文件。在这方面,它与函数式编程中的higher-order function flatmap非常相似。这就是为什么gulp-foreach的作者gulp-flatmap拥有recently renamed插件的原因。

您感兴趣的是访问流中的每个文件并打印其路径,这就是higher-order function map的情况。正确的插件是map-streamgulp-tap(这是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;
    }));
});

答案 1 :(得分:0)

您没有看到所有文件的原因是因为您没有返回承诺,并且任务在迭代所有文件之前完成

像这样返回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;
    }))

})