0

I'm trying to figure out a way to break out a watch target from the rest of the block. Currently my watch target looks like this:

watch: {
  options: {
    // Parent-level options
  },
  coffee: {
    // ...
  },
  stylus: {
    // ...
  },
  test: {
    options: {
      // Test-specific options
    },
    files: {
      // ...
    }
    tasks: {
      // ...
    }
  }
}

The problem I'm facing is that my test options include a different livereload port than the top level, so I can simultaneously run grunt server and grunt test with livereloading and not have them interfere with each other.

Beneath that, I have a server alias and a test alias. What I'm looking for is to break the test watch target out into another task so I can simply run watch in my server alias and something like watch-test for testing, such that the server task doesn't run the test target.

Any ideas? Please let me know if I've left out anything important or this isn't clear. Thanks!

richgilbank
  • 384
  • 2
  • 9

2 Answers2

1

A solution I've used is to define multiple watch targets and rename the watch task like so:

watch: {
    scripts: {
        files: ['js/**/*.js'],
        tasks: ['concat', 'uglify'],
        options: {
            spawn: false
        }
    }
},

// Don't uglify in dev task
watchdev: {
    scripts: {
        files: ['js/**/*.js'],
        tasks: ['concat'],
        options: {
            spawn: false
        }
    }
}

grunt.loadNpmTasks('grunt-contrib-watch');
// Rename watch to watchdev and load it again
grunt.renameTask('watch', 'watchdev');
grunt.loadNpmTasks('grunt-contrib-watch');

grunt.registerTask('default', ['watch']);
grunt.registerTask('dev', ['watchdev']);
Matt Stow
  • 6,053
  • 6
  • 24
  • 26
0

Since grunt watch is a multi task, running grunt watch from the CLI means that all targets are watched. You can instead run one target out of those by simply running grunt watch:test or grunt watch:server, whatever is your preference. Hope that helps.

Edit: It might be appropriate to point out this issue on the watch issue tracker:

https://github.com/gruntjs/grunt-contrib-watch/issues/206

The code in the issue is a little old, I would recommend newer code to require lodash and use _ instead of grunt.util._ (that utility is now deprecated). So the code would look like this:

var _ = require('lodash');

module.exports = function(grunt) {
    // Run with: grunt switchwatch:target1:target2 to only watch those targets
    grunt.registerTask('switchwatch', function() {
        var targets = Array.prototype.slice.call(arguments, 0);
        Object.keys(grunt.config('watch')).filter(function(target) {
            return !(_.indexOf(targets, target) !== -1);
        }).forEach(function(target) {
            grunt.log.writeln('Ignoring ' + target + '...');
            grunt.config(['watch', target], {files: []});
        });
        grunt.task.run('watch');
    });
}

Still, you could modify your server task to run something like switchwatch:coffee:stylus:server:

grunt.registerTask('server', [/* rest of your tasks */, 'switchwatch:coffee:stylus:server']);
Ben
  • 10,106
  • 3
  • 40
  • 58
  • Thanks, but I'm not calling the watch task directly from CLI, but rather from the aliased tasks `server` and `test` (how Yeoman sets it up). So, essentially I want `grunt server` to run the `watch` task (thereby watching multiple targets) WITHOUT the `test` target, and `grunt test` to run `watch:test`. Does that sort of make sense? Thanks again! – richgilbank Dec 30 '13 at 18:55