1

I'm in the process of migrating from gulp@3.9.1 to gulp@4.0.2 and upgrading my gulp dependencies in the process. I have the following task in my gulpfile, where you can assume directories is just an array of directories I want to perform this operation on:

var gulp = require('gulp');
var ngAnnotate = require('gulp-ng-annotate'); //annotates dependencies in Angular components
var rev = require('gulp-rev'); //appends a hash to the end of file names to eliminate stale cached files
var revReplace = require('gulp-rev-replace');
var uglify = require('gulp-uglify'); // minimizes javascript files
var compressCss = require('gulp-minify-css');
var useref = require('gulp-useref'); // replaces style and script blocks in HTML files
var filter = require('gulp-filter');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');

function minify() {
    var tasks = directories.map(function (directory) {
        var cssFilter = filter("**/all.min.css", {restore:true});
        var jsAppFilter = filter("**/app.min.js", {restore:true});
        var jsFilter = filter("**/*.js", {restore:true});

        return gulp.src(dstBasePath + directory + "index.html", {allowEmpty: true})
            .pipe(useref())
            .pipe(cssFilter)
            .pipe(compressCss({keepSpecialComments:false}))
            .pipe(rev())
            .pipe(cssFilter.restore)
            .pipe(jsAppFilter)
            .pipe(sourcemaps.init())
            .pipe(ngAnnotate({add:true, single_quotes:true}))
            .pipe(jsAppFilter.restore)
            .pipe(jsFilter)
            .pipe(uglify())
            .pipe(rev())
            .pipe(jsFilter.restore)
            .pipe(revReplace())
            .pipe(sourcemaps.write('.'))    // sourcemaps need to be written to same folder for Datadog upload to work
            .pipe(gulp.dest(dstBasePath + directory))
    });

    return merge(tasks);
}

Why would this result in the error "Did you forget to signal async completion?" from Gulp when running the task? Note that I'm using Gulp 4. I've tried passing a callback done to this task, and adding .addListener('end', done) to the final pipe, but this causes my merged stream to end prematurely (presumably when the first one ends). So perhaps one of these plugins is not signaling when it's completed, but how would you even get this to work otherwise? Thanks for any insight you can provide.

Daniel Allen
  • 894
  • 1
  • 10
  • 23

2 Answers2

0

return merge(folders.map(function (folder) { // this has worked for me in the past

as has this form without merge

gulp.task('init', function (done) {

  var zips = getZips(zipsPath);

  var tasks = zips.map(function (zip) {
  
    return gulp.src(zipsPath + "/" +  zip)
              
      .pipe(unzip({ keepEmpty: true }))
      
      .pipe(gulp.dest(path.join("src", path.basename(zip, ".zip"))))
      
      .on('end', function() {   // this bit is necessary
        done();
       });
  });

  return tasks;
});
Mark
  • 143,421
  • 24
  • 428
  • 436
0

Gulp 4 requires that you signal async completion. There's some good information about it in this answer to a similar question: Gulp error: The following tasks did not complete: Did you forget to signal async completion?

I had a similar case where I was returning a merged set of tasks, and I was able to resolve the error by making the function async and awaiting the merge. My case looked something like this:

gulp.task("build", async function () {
    ...
    return await merge(tasks);
});

so I think you should be able to do something like

async function minify(){
    ...
    return await merge(tasks);
}
ryanwawr
  • 1
  • 3