0

I am attempting to re-run my gulp build when gulpfile.js changes, but I am having issues with the method all of my research has lead me to.

I have one watcher for all my less and javascript files and a configuration object that has the list of files to watch, how they are output, etc. This is a stripped-down example of what it looks like:

var $ = require('gulp-load-plugins')();

var config = {
    root: rootPath,
    output: {
        app: 'app',
        vendor: 'vendor'
    }, // ...
};

gulp.task('default', ['build', 'watch']);

gulp.task('build', ['clean', 'less:app', 'less:theme', 'css:vendor', 'js:app', 'js:vendor', 'rev', 'css:copyfonts']);

gulp.task('watch', function () {
    var allFiles = config.styles.appSrc
        .concat(config.styles.vendorSrc)
        .concat(config.scripts.appSrc)
        .concat(config.scripts.vendorSrc);

    $.watch(allFiles, function () {
        gulp.start('default');
    });
});

gulp.task('watch:gulp', function () {
    var p;

    gulp.watch('gulpfile.js', spawnUpdatedGulp);

    spawnUpdatedGulp();

    function spawnUpdatedGulp() {
        if (p) {
            p.kill();
        }

        p = spawn('gulp', ['default', '--color'], { stdio: 'inherit' });
    }
});

// .. other build tasks .. 

The above code shows how I tried the accepted answer to this: How can Gulp be restarted upon each Gulpfile change?

However, it has a major issue. When I run watch:gulp, it runs the build just fine, and everything is great. The config.output.app variable is how the app specific css and js files are named, so my test case has been:

  1. run gulp:watch, check that the css output is named according to config.output.app
  2. change config.output.app, and perform step #1 again
  3. save any random javascript file that it is watching, and see if it builds correctly

Step 3 is riddled with permission errors because of multiple watchers on the files, and this only gets worse the more I repeat steps 1 and 2. Visual Studio will even freeze.

I have not found a way to clean up the old watchers. I tried to manually kill them like this:

var appFileWatcher;

gulp.task('watch', function () {
    var allFiles = config.styles.appSrc
        .concat(config.styles.vendorSrc)
        .concat(config.scripts.appSrc)
        .concat(config.scripts.vendorSrc);

    appFileWatcher = $.watch(allFiles, function () {
        gulp.start('default');
    });
});

gulp.task('watch:gulp', function () {
    var p;

    var gulpWatcher = $.watch('gulpfile.js', spawnUpdatedGulp);

    spawnUpdatedGulp();

    function spawnUpdatedGulp() {
        if (p) {
            p.kill();
        }

        if (appFileWatcher) {
            appFileWatcher.unwatch();
        }

        gulpWatcher.unwatch();

        p = spawn('gulp', ['default', '--color'], { stdio: 'inherit' });
    }
});

This also does not work. I still get multiple watchers trying to perform the build when I perform my same test case.

How do I kill those watchers that stay around after the new gulp process is spawned?

Community
  • 1
  • 1
DerekMT12
  • 1,329
  • 11
  • 15
  • I use a single watcher who manages all that stuff with [nodemon](https://www.npmjs.com/package/gulp-nodemon). – rmjoia Jan 21 '16 at 19:49
  • I looked into gulp-nodemon, but all of the examples I saw referenced `server.js` or `app.js`, but there were no examples on what that file would contain. I don't have an express app, so I don't need to reload a web app. It seems kind of overkill to have to create a self hosted app to just restart gulp. If I could put 'gulpfile.js' instead of server or app.js, that would make sense to me, but I didn't see that as an example anywhere. – DerekMT12 Jan 21 '16 at 20:03

0 Answers0