How to run two grunt watch tasks simultaneously

ⅰ亾dé卋堺 提交于 2019-11-28 15:57:32

I've found using grunt-concurrent works:

concurrent: {
  options: {
    logConcurrentOutput: true
  },
  prod: {
    tasks: ["watch:A", "watch:C"]
  },
  dev: {
    tasks: ["watch:B", "watch:C"]
  }
}

Then:

grunt.registerTask("prod", ["concurrent:prod"]);
grunt.registerTask("dev", ["concurrent:dev"]);

EDIT: concurrent now has a logConcurrentOutput option! More info here: https://github.com/sindresorhus/grunt-concurrent#logconcurrentoutput.

Watch is a weirdly concurrent but blocking task, so you have to be creative to get multitask-like functionality working.

Concurrent loses all output from the watch tasks, which isn't ideal.

Try dynamically writing the config object in a custom task:

grunt.registerTask('watch:test', function() {
  // Configuration for watch:test tasks.
  var config = {
    options: {
      interrupt: true
    },
    unit: {
      files: [
        'test/unit/**/*.spec.coffee'
      ],
      tasks: ['karma:unit']
    },
    integration: {
      files: [
        'test/integration/**/*.rb',
        '.tmp/scripts/**/*.js'
      ],
      tasks: ['exec:rspec']
    }
  };

  grunt.config('watch', config);
  grunt.task.run('watch');
});

The best and only working solution is there : https://npmjs.org/package/grunt-focus Add this plugin and then :

focus: {
            sources: {
                include: ['js', 'html', 'css', 'grunt']
            },
            testu: {
                include: ['js', 'html', 'css', 'testu', 'grunt']
            },
            testi: {
                include: ['js', 'html', 'css', 'testu', 'testi', 'grunt']
            }
        },
        watch: {
            js: {
                files: paths.js,
                tasks: ['jshint'],
                options: {
                    livereload: true
                }
            },
            html: {
                files: paths.html,
                options: {
                    livereload: true
                }
            },
            css: {
                files: paths.css,
                tasks: ['csslint'],
                options: {
                    livereload: true
                }
            },
            testu: {
                files: ['test/**/*.js', 'test/**/*.css'],
                tasks: ['mochaTest'],
                options: {}
            },
            testi: {
                files: ['test/**/*.js', 'test/**/*.css'],
                tasks: ['exec:cleanTestDB', 'protractor_webdriver', 'protractor'],
                options: {}
            },
            grunt: {
                files: ['Gruntfile.js', 'server/config/env/*.js'],
                options: {
                    reload: true
                }
            }
        }

Then you use focus:sources or focus:testu as your convenience.

JM.

grunt-concurrent or grunt-focus are both good solutions, but both of them break livereload functionality.

My solution to this is to compose the watch configuration dynamically, with the assumption that you won't be running both configuration at the same time.

You can do something like this

grunt.config.merge({
  watch: {
    options: {
      livereload: true
    },
    C: {
      files: "js/dev/**/*.html",
      tasks: ["copy"]
    }
  }
});

grunt.registerTask('watch-forProd', function () {
  grunt.config.merge({
    watch: {
      A: {
        files: "js/dev/**/*.coffee",
        tasks: ["coffee", "requirejs"]
      }
    }
  });

  grunt.task.run('watch');
});

grunt.registerTask('watch-forDev', function () {
  grunt.config.merge({
    watch: {
      B: {
        files: "js/dev/**/*.coffee",
        tasks: ["coffee"]
      }
    }
  });

  grunt.task.run('watch');
});

grunt.registerTask("prod", ["watch-forProd"]);
grunt.registerTask("dev", ["watch-forDev"]);

SEPTEMBER 2018

You don't need to use grunt-concurrent anymore grunt now has this built in, here is a sample from one of my current projects...

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: {
            theme: {
                files: {
                    '../../web/sites/all/themes/ifafri/css/generated/theme_ifafri_master.css' : '../../web/sites/all/themes/ifafri/css/master.scss'
                }
            },
            bootstrap: {
                files: {
                    '../../web/sites/all/themes/ifafri/css/generated/theme_ifafri_bootstrap.css' : '../../web/sites/all/themes/ifafri/css/bootstrap/master.scss' 
                }
            }
        },
        watch: {
            theme: {
                files: '../../web/sites/all/themes/ifafri/css/*.scss',
                tasks: ['sass:theme'],
                options: {
                    spawn: false,
                    livereload: true,
                    nospawn: false
                }
            },
            bootstrap: {
                files: '../../web/sites/all/themes/ifafri/css/bootstrap/*.scss',
                tasks: ['sass:bootstrap'],
                options: {
                    spawn: false,
                    livereload: true,
                    nospawn: false
                }
            }
    }
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-livereload');
    grunt.registerTask('default',['watch']);
}

Without worrying grunt.registerTask() in Gruntfile.js, I sometimes run grunt as background processes into the command line:

$ grunt watch:A &
$ grunt watch:C &

You can make the commands as a batch script for more convenience. Hopefully it helps.

I know this not answer directly to the question, but my solution is now to use Gulp instead of Grunt. With Gulp you code and not only configure. So you are more free to do what you want.

JM.

Concurrent works fine for me

concurrent: {
            options: {
                logConcurrentOutput: true
            },
            set1: ['watch:html', 'watch:styles'],
        },

grunt.registerTask('default', 'watch');
grunt.registerTask('htmlcss', ['concurrent:set1']);

Just change the port address and the livereload port. For eg. if the port is 9000 change it to 8000 and live reload from 35729 to 36729

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!