Gulp: Gulp 4: Functions that return gulp.series or gulp.parallel do not allow tasks to complete

Created on 5 Feb 2017  路  18Comments  路  Source: gulpjs/gulp

What were you expecting to happen?

I wrote up this gulp 4 code:

``````js
//reloads the browser
function reload(done){
browserSync.reload();
done();
}

//If running in PHP mode, convert the html files to php files before reloading
gulp.task('pug:reload', (done)=>{
if (config.serve === 'php'){
return gulp.series('convert-HTML', reload);
} else {
return gulp.series(reload);
}
});

//The main pug task
gulp.task('pug', gulp.series(
'pug:compile',
'pug:reload',//the one causing the issue
));
``````

When running in PHP mode, I expected that the main pug task would essentially equate to this:

js gulp.task('pug', gulp.series( 'pug:compile', gulp.series('convert-HTML', reload), ));

When running in HTML mode, I expected that the main pug task would essentially equate to this:

js gulp.task('pug', gulp.series( 'pug:compile', gulp.series(reload), ));

I tested putting the code inline like that just to make sure that the tasks weren't broken. It did indeed work as expected.

What actually happened?

When I tried to run the 'pug:reload' task, it came up with this error:

[00:45:34] The following tasks did not complete: pug:reload [00:45:34] Did you forget to signal async completion?

The only way I could get around this was to do this with my code:

``````js
var pugReload = gulp.series(reload);
if (config.serve === 'php') pugReload = gulp.series('convert-HTML', reload);

gulp.task('pug', gulp.series(
'pug:compile',
pugReload,
));
``````

It was then able to compile successfully.

What version of gulp are you using?

[01:10:37] CLI version 1.2.2 [01:10:37] Local version 4.0.0-alpha.2

What versions of npm and node are you using?

npm: 3.10.6
node: 4.4.7

Most helpful comment

This should really be explained better in the docs, I've just spent a couple of hours trying to figure out how to run a basic gulp setup...

import gulp from 'gulp'
import sass from 'gulp-sass'
import pug from 'gulp-pug'

gulp.task('styles', () => {
    return gulp.src('src/sass/**/*.scss')
        .pipe(sass())
        .pipe(
            gulp.dest('./dist')
        )
})

gulp.task('markup', () => {
    return gulp.src('src/pug/**/*.pug')
        .pipe(pug())
        .pipe(
            gulp.dest('./dist')
        )
})

gulp.task('build', (done) => (
    gulp.series('styles', 'markup')(done)
))

Had I not found this issue, I'd pull all of my hair out

All 18 comments

gulp.series and gulp.parallel return functions that may be passed into gulp.task as task functions.

You can try making a function that will return the correct task function that you need and then call that function and pass the results into the task like this:

function reloadFactory() {
  if (config.serve === 'php'){
    return gulp.series('convert-HTML', reload);
  } else {
    return gulp.series(reload);
  }
}

gulp.task('pug:reload', reloadFactory());
const convertAndReload = gulp.series('convert-HTML', reload)
gulp.task('pug:reload', (done)=>{
  if (config.serve === 'php'){
    convertAndReload(done);
  } else {
    reload(done)
  }
});

Shouldn't this work for you? gulp.series returns an async function, so you have to call it.

It does but it is a poor way to do it. You should generate tasks upon load, not switch upon execution.

@phated Yeah, agree on that - just clarifying how the functions work for anyone reading this in the future. gulp.series and gulp.parallel aren't a dark art, just functions that return another (callable) function.

@doowb Sorry, I should have clarified. I did try the method you mentioned before I posted the issue however that didn't work either.

Essentially my issue boils down to this. Whenever you use this pattern in your code, no matter how you implement it, it doesn't seem to allow the gulp task to end.

js return gulp.series('task-1','task-2'); // or return gulp.parallel('task-1','task-2');

@Dan503 Yeah, a task function can return a few things to signal completion: A promise, a stream, or nothing (and you call the callback passed into the args)

You're returning a function, which does not signal completion and that function will not be executed.

Ahh ok, I get it now. Thanks for the help :)

I had a thought though. Since the main reason that the task fails is because the return function isn't being called, I thought I would try calling it from the return statement.

Using this syntax works :)

js gulp.task('pug:reload', (done)=>{ if (config.serve === 'php'){ return gulp.series('convert-HTML', reload)(done); } else { return gulp.series(reload)(done); } });

This should really be explained better in the docs, I've just spent a couple of hours trying to figure out how to run a basic gulp setup...

import gulp from 'gulp'
import sass from 'gulp-sass'
import pug from 'gulp-pug'

gulp.task('styles', () => {
    return gulp.src('src/sass/**/*.scss')
        .pipe(sass())
        .pipe(
            gulp.dest('./dist')
        )
})

gulp.task('markup', () => {
    return gulp.src('src/pug/**/*.pug')
        .pipe(pug())
        .pipe(
            gulp.dest('./dist')
        )
})

gulp.task('build', (done) => (
    gulp.series('styles', 'markup')(done)
))

Had I not found this issue, I'd pull all of my hair out

@selrond you have over complicated it.

Instead of doing this:
js gulp.task('build', (done) => ( gulp.series('styles', 'markup')(done) ))

Just do this:
js gulp.task('build', gulp.series('styles', 'markup'))

@Dan503 how so?

Try it. It should work.

gulp.series() returns an uncalled function that takes done as it's first parameter.

Now take a look at your code
js (done) => ( gulp.series('styles', 'markup')(done) )
That anonymous function is an uncalled function that takes done as it's first parameter.

@Dan503 Now I see, thank you!
I guess this should be stated in the docs...

This is Gulp 4 syntax. It hasn't officially been released yet. The official docs only cover Gulp 3 syntax since that is the official version.

This is basic Gulp 4 functionality. Anywhere that documents Gulp 4 clearly documents this.

Plus the documentation is not complete. We're currently looking for sponsors to help us pay to get them written: https://opencollective.com/gulpjs

But the README doesn't have any gulp.task or (done) => gulp.series(..)(done) right now https://github.com/gulpjs/gulp/blob/24e202b3a3dc9e1eecd3fc1e4b69e2b5379928ea/README.md

That's very confusing, when I come into the problem switching from 3.x to Gulp 4

In case anyone comes here looking for a solution without gulp.task(...), I was able to achieve it using:

function build(done) {
  function styles() {
    return gulp.src(...);
  }

  function markup() {
    return gulp.src(...);
  }

  return gulp.series(styles, markup)(done);
}

You can also do this with Gulp 4.

exports.build = gulp.series(styles, markup);

That would be the more correct way to do it 馃槄

The return gulp.series(X, Y)(done) pattern is a bit of a hack.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cgc picture cgc  路  3Comments

amio picture amio  路  3Comments

zellwk picture zellwk  路  3Comments

LuckStock picture LuckStock  路  4Comments

XaBerr picture XaBerr  路  3Comments