【问题标题】:What about this combination of gulp-concat and lazypipe is causing an error using gulp 4?gulp-concat 和lazypipe 的这种组合使用gulp 4 会导致错误吗?
【发布时间】:2017-02-27 03:10:03
【问题描述】:

我正在从 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());
});

任何建议表示赞赏!

【问题讨论】:

    标签: javascript gulp build-tools gulp-concat gulp-4


    【解决方案1】:

    这是 known issue 与 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);
    });
    

    或者,在buildFiles() 之后添加任何.pipe() 应该可以解决这个问题,即使是实际上并没有像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());
    });
    

    【讨论】:

    • 感谢清晰详细的解释,非常感谢!
    【解决方案2】:

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

    我不得不说我现在不想念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 串行和并行结合起来。希望这对正在为此苦苦挣扎的一些人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      相关资源
      最近更新 更多