11

我正在从 Gulp 3 升级到 4,我遇到了一个错误:

The following tasks did not complete: build
Did you forget to signal async completion?

我明白它在说什么,但不明白为什么这段代码会触发它。

错误与否,任务完成(文件被连接并写入 dest)。在没有惰性管道的情况下执行相同的代码不会导致错误,并且在惰性管道中删除连接也可以修复错误。

将整个事物包装在创建流(如合并流)的东西中可以解决问题。我猜想 gulp-concat 和lazypipe 之间的交互会阻止流被正确返回。

这是(简化的)任务:

gulp.task('build', function() {
    var dest = 'build';

    var buildFiles = lazypipe()
        .pipe(plugins.concat, 'cat.js') // Task will complete if I remove this
        .pipe(gulp.dest, dest);

    // This works
    // return gulp.src(src('js/**/*.js'))
    //     .pipe(plugins.concat('cat.js'))
    //     .pipe(gulp.dest(dest));

    // This doesn't (unless you wrap it in a stream-making function)
    return gulp.src(src('js/**/*.js'))
        .pipe(buildFiles());
});

任何建议表示赞赏!

4

2 回答 2

14

这是与 gulp 4 一起使用时的一个已知问题lazypipe,并且不会在不久的将来修复。引用该问题:

OverZealous 于 2015 年 12 月 20 日发表评论
截至目前,我无意在 Gulp 4 上使用惰性管道。

据我所知,这个问题是由 gulp 4 使用的事实引起的,async-done这说明了它的流支持:

注意:仅支持实际流,不支持虚假流;因此,event-stream不支持类似的模块。

当你使用lazypipe()作为最后一个管道时,你得到的是一个流,它没有很多在 gulp 中使用流时通常具有的属性。您可以通过记录流来亲自查看:

// console output shows lots of properties
console.log(gulp.src(src('js/**/*.js'))
  .pipe(plugins.concat('cat.js'))
  .pipe(gulp.dest(dest))); 

// console output shows much fewer properties
console.log(gulp.src(src('js/**/*.js'))
  .pipe(buildFiles())); 

这可能是 gulp 认为第二个流是“假流”并且没有正确检测流何时完成的原因。

此时您唯一的选择是某种解决方法。最简单的解决方法(不需要任何额外的包)就是在cb你的任务中添加一个回调函数并监听'end'事件:

gulp.task('build', function(cb) {
  var dest = 'build';

  var buildFiles = lazypipe()
   .pipe(plugins.concat, 'cat.js') 
   .pipe(gulp.dest, dest);

  gulp.src(src('js/**/*.js'))
   .pipe(buildFiles())
   .on('end', cb);
});

或者,添加任何.pipe()afterbuildFiles()应该可以解决这个问题,即使是一个实际上并没有做任何事情的人gutil.noop()

var gutil = require('gulp-util');

gulp.task('build', function() {
  var dest = 'build';

  var buildFiles = lazypipe()
    .pipe(plugins.concat, 'cat.js') 
    .pipe(gulp.dest, dest);

  return gulp.src(src('js/**/*.js'))
    .pipe(buildFiles())
    .pipe(gutil.noop());
});
于 2016-10-18T06:50:43.330 回答
0

所以错误很明显。我必须进行一些重构以使 gulp 4 再次工作。我最终制作了一些额外的方法,这些方法采用源和目标并执行以前由我的lazypipe 实现完成的任务。

我不得不说我现在不怀念lazypipe了。这只是一种不同的方法。我确实完成了一些额外的任务,但他们使用标准方法,如下例所示:

// previously a lazypipe, now just a method to return from a gulp4 task 
const _processJS = (sources, destination) => {

  return src(sources)
    .pipe(minify(...))
    .pipe(uglify(...))
    .pipe(obfuscate(...))
    .pipe(whatever())
    .pipe(dest(destination));

};

const jsTaskXStep1 = ()=>{
  return src(...).pipe(...).pipe(...).pipe(dest(...));
};

const jsTaskXStep2 = ()=>{
  return _processJS(['./src/js/x/**/*.js'], './dist/js');
};

const jsTaskYStep1 = ()=>{
  return src(...).pipe(...).pipe(...).pipe(dest(...));
};

const jsTaskYStep2 = ()=>{
  return _processJS(['./src/js/y/**/*.js'], './dist/js');
};

const jsTaskX = series(jsTaskXStep1, jsTaskXStep2);
const jsTaskY = series(jsTaskYStep1, jsTaskYStep2);

module.exports = {
  js: parallel(jsTaskX, jsTaskY),
  css: ...,
  widgets: ...,
  ...
  default: parallel(js, css, widgets, series(...), ...); 
}

所以基本上你可以在这个例子中把你的惰性管道的东西放在像 _processJS 这样的方法中。然后创建使用它的任务,并将所有内容与 gulp 串行和并行结合起来。希望这可以帮助一些正在为此苦苦挣扎的人。

于 2019-07-11T11:21:20.523 回答