0

I can't figure out why I'm getting

Did you forget to signal async completion?

Here's my setup:

gulp.task('compile-ts', () => {
    return tsProject.src(config.files.src.ts)
        .pipe($.tap((file, t) => {
            logVerbose('Compiling "' + file.path + "'");
        }))
        .pipe($.sourcemaps.init())
        .pipe($.typescript(tsProject))
        .pipe($.sourcemaps.write('./'))
        .pipe($.chmod(755))
        .pipe(gulp.dest(config.dist));
});

gulp.task('copy-assets', () => {
    return gulp.src(config.files.src.css_html_js, { base: config.src })
        .pipe($.tap((file, t) => {
            logVerbose('Copying "' + getFileName(file.path) + "'");
        }))
        .pipe($.chmod(755))
        .pipe(gulp.dest(config.dist));
});

gulp.task('browser-sync', (done) => {
    browserSync.init({
        "port": 3000,
        "startPath": "dist/index.html",
        "browser": "chrome",
        "logLevel": "silent",
        "server": {
            "middleware": {
                "0": null
            }
        }
    }, done);  
    process.on('exit', () => {
        browserSync.exit();
    });
})

gulp.task('watch', gulp.parallel(() => {
    gulp.watch(config.files.ts, gulp.series('compile-ts'));
}, () => {
    gulp.watch(config.files.css_html_js, gulp.series('copy-assets'));
}));

gulp.task('serve-dist', gulp.parallel('watch', 'browser-sync'));

According to the stacktrace, the offending line is

gulp.watch(config.files.ts, gulp.series('compile-ts'));

inside the watch task. The task compile-ts is working and it returns a stream, which should be enough to signal completion. But why am I getting the error anyway?

This is gulp@4.0.0-alpha.2.

EDIT:

Changing the watch task to

gulp.task('watch', (done) => {
    gulp.watch(config.files.css_html_js, gulp.series('copy-assets'));
    gulp.watch(config.files.ts, gulp.series('compile-ts'));
    done();
});

I don't get any errors anymore, but the task is finished within 4ms and does nothing at all. If I remove the done part, I get the same error again.

EDIT2: I split the tasks up some more to be able to pinpoint the problem,

gulp.task('watch-ts', () => {
    return gulp.watch(config.files.ts, gulp.series('compile-ts'));
});

gulp.task('watch-assets', () => {
    return gulp.watch(config.files.css_html_js, gulp.series('copy-assets'));
});

gulp.task('watch', gulp.parallel('watch-ts', 'watch-assets'));

Now watch-ts and watch-assets both give me that error message. Either of which returns a stream as far as I can tell.

Thorsten Westheider
  • 10,572
  • 14
  • 55
  • 97
  • Possible duplicate of [Gulp error: The following tasks did not complete: Did you forget to signal async completion?](http://stackoverflow.com/questions/36897877/gulp-error-the-following-tasks-did-not-complete-did-you-forget-to-signal-async) – Sven Schoenung Jul 13 '16 at 14:24
  • Also doesn't `tsProject.src()` return a stream? [`gulp.watch()`](https://github.com/gulpjs/gulp/blob/4.0/docs/API.md#gulpwatchglobs-opts-fn) expects a string or an array of strings. – Sven Schoenung Jul 13 '16 at 14:29
  • Corrected. Doesn't change the outcome though and have checked the proposed answer before posting my question as - in my opinion - I'm returning a stream (= your answer item 1.) – Thorsten Westheider Jul 13 '16 at 14:58
  • It does change the outcome. Your `watch` task is now correctly signaling async completion. Of course it's not going to do anything unless you modify one of the watched files (or use the `ignoreInitial` option). – Sven Schoenung Jul 13 '16 at 15:31

1 Answers1

1

You always need to signal async completion in every function that composes a task. Not just those that are asynchrounous. Not just those that use streams. If you're not returning a stream in a function, you still need to signal async completion somehow (usually by invoking a callback).

So your first edit was already correct:

gulp.task('watch', (done) => {
  gulp.watch(config.files.css_html_js, gulp.series('copy-assets'));
  gulp.watch(config.files.ts, gulp.series('compile-ts'));
  done();
});

Invoking the callback here makes sure that gulp knows that your watch task has completed successfully. "Completed successfully" in this case means that your task has started the two watches. Both watches will continue to run even after the watch job has finished. So there's nothing wrong with the fact that the watch task terminates after 4ms.

Starting a watch however does not automatically trigger the execution of the listener function. You'll have to modify one of the watched files first. Alternatively you can pass the ignoreInitial option to gulp.watch() which will trigger the watch when it first starts up:

gulp.task('watch', (done) => {
  gulp.watch(config.files.css_html_js, {ignoreInitial:false}, gulp.series('copy-assets'));
  gulp.watch(config.files.ts, {ignoreInitial:false}, gulp.series('compile-ts'));
  done();
});
Sven Schoenung
  • 30,224
  • 8
  • 65
  • 70
  • Thanks for pointing this out Sven, it's working now. I said it did nothing because it actually was doing nothing at all. If you look closely, you'll see that e.g. the `compile-ts` task refers to a glob var `config.files.src.ts`, compare this to the glob var from the watch and - lightning strikes. So actually the glob was undefined and the error message was misleading. – Thorsten Westheider Jul 13 '16 at 16:18