Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What about this combination of gulp-concat and lazypipe is causing an error using gulp 4?

I'm upgrading from Gulp 3 to 4, and I'm running into an error:

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

I understand what it's saying, but can't understand why this code is triggering it.

Error or not, the task completes (the files are concatenated and written to dest). Executing the same code without lazypipe results in no error, and removing the concatenation within lazypipe also fixes the error.

Wrapping the whole thing in something that creates a stream (like merge-stream) fixes the issue. I guess something about the interaction between gulp-concat and lazypipe is preventing a stream from being correctly returned.

Here's the (simplified) task:

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());
});

Any advice appreciated!

like image 404
goodforenergy Avatar asked Oct 18 '16 01:10

goodforenergy


1 Answers

This is a known issue when using lazypipe with gulp 4 and it's not going to be fixed in the near future. Quote from that issue:

OverZealous commented on 20 Dec 2015
As of now, I have no intention of making lazypipe work on Gulp 4.

As far as I can tell this issue is caused by the fact that gulp 4 uses async-done which has this to say about its stream support:

Note: Only actual streams are supported, not faux-streams; Therefore, modules like event-stream are not supported.

When you use lazypipe() as the last pipe what you get is a stream that doesn't have a lot of the properties that you usually have when working with streams in gulp. You can see this for yourself by logging the streams:

// 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())); 

This is probably the reason why gulp considers the second stream to be a "faux-stream" and doesn't properly detect when the stream has finished.

Your only option at this point is some kind of workaround. The easiest workaround (which doesn't require any additional packages) is to just add a callback function cb to your task and listen for the 'end' event:

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);
});

Alternatively, adding any .pipe() after buildFiles() should fix this, even one that doesn't actually do anything like 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());
});
like image 66
Sven Schoenung Avatar answered Sep 24 '22 08:09

Sven Schoenung