Skip to content

Problems with gulp 4 watch #175

@iby

Description

@iby

I found quite a few watch-related issues, unfortunately none helped me with my case. I noticed two problems:

  1. When stopping the task with Control+C the script fails with the following error. If I remove watchFiles or startNodemon/BrowserSync tasks, everything works fine.

    [14:09:04] The following tasks did not complete: serve, <parallel>, watchFiles
    [14:09:04] Did you forget to signal async completion?
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! @ serve: `gulp serve`
    npm ERR! Exit status 1
  2. After trial and error I figured that if a callback gets passed/invoked in watch files task it would prevent the termination failure, however in approx. ⅓ launches the file watching wouldn't work. Literally. Upon one launch it behaves as expected when changing a file. Upon next launch it wouldn't see changes at all and won't run.

Here's the gulp file:

import BrowserSync from "browser-sync";
import del from "del";
import gulp from "gulp";

import changed from "gulp-changed";
import nodemon from "gulp-nodemon";
import ts from "gulp-typescript";

const browserSync = BrowserSync.create();
const tsProject = ts.createProject("./tsconfig.json");

function cleanProduct() {
    return del(["./product/js", "./product/css", "./entrypoint"]);
}

function buildJS() {
    return gulp
        .src(["./source/ts/**/*.ts", "./source/d.ts/**/*.ts"])
        .pipe(changed("./product/js", {extension: ".js"}))
        .pipe(tsProject())
        .pipe(gulp.dest("./product/js"))
        .pipe(browserSync.stream());
}

function watchFiles() {
    gulp.watch("./source/ts/**/*.ts", gulp.series(buildJS));
}

// This callback setup is needed for correct BrowserSync initialization in case you wonder…
function startNodemon(cb) {
    let isStarting = false;

    let server = nodemon({
        script: "./product/js/index.js",
        ignore: "./product/js/**/*Test.js",
        watch: "./product/js/**/*.js",
        stdout: false,
        ext: ""
    });

    const finalize = () => {
        if (!isStarting) { return; }
        isStarting = false;
        cb();
    };

    server.on("start", () => {
        isStarting = true;
        setTimeout(finalize, 5000);
    });

    server.on("stdout", (stdout) => {
        process.stdout.write(stdout); // pass the stdout through
        if (isStarting) { finalize(); }
    });
}

function startBrowserSync(cb) {
    browserSync.init({
        proxy: "http://localhost:8080",
        port: 8081,
        ui: false
    }, cb);
}

const build = gulp.series(cleanProduct, gulp.parallel(buildJS));
const serve = gulp.series(build, gulp.parallel(gulp.series(startNodemon, startBrowserSync), watchFiles));

exports.default = build;
exports.build = build;
exports.serve = serve;

I tried removing BrowserSync out of the equation, but it doesn't seem to be making any difference. Is there any special treatment for the module or other workaround to make it work without throwing errors on exit and not using a callback with file watch task?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions