Grunt-contrib-watch with grunt-contrib-connect

744 views Asked by At

Unfortunately, grunt-contrib-watch and grunt-contrib-connect don't seem to be playing nice.

On the grunt-contrib-connect readme it says:

Note that this server only runs as long as grunt is running. Once grunt's tasks have completed, the web server stops. This behavior can be changed with the keepalive option, and can be enabled ad-hoc by running the task like grunt connect::keepalive.

Fine. But what if I want to run my watch task in tandem with the connect server? Like so:

connect: {
  server: {
    options: {
      port: 8000,
      hostname: 'localhost',
      keepalive: true
    }
  }
},
watch: {
  options: {
    livereload: true
  },
  files: ['**'],
  tasks: ['connect'],
}

Here, the connect task runs when a file is changed. If I set the connect's keepalive option to true, then grunt-contrib-watch stops watching because it technically hasn't finished it's task. If I falsify the keepalive option, then the connect server dies after it has finished the tasks.

Yes, I could run the commands...

$ grunt connect
$ grunt watch

...in separate shells, but is there no way of running them with one command?

2

There are 2 answers

0
CaptEmulation On

I use grunt-nodemon, which encapsulates watch and a nodejs launcher in a single task:

nodemon: {
  dev: {
    script: 'app.js',
    options: {
      ignore: [
        'node_modules/**',
        'public/**'
      ],
      ext: 'js'
    }
  }
}

Then executed with:

$ grunt nodemon:dev

Now, nodemon only launches the app.js script with nodejs, so you will need a small app.js to load a static static express server:

var express = require('express');
var server = express(); // better instead
server.configure(function(){
  server.use(express.static(__dirname + '/public'));
});

server.listen(3000);
1
discoman On

Livereload in grunt-contrib-watch informs for changes in files at a port here below you can see it is at 35729.

On the other hand the livereload in grunt-contrib-connect listens for changes at the port 35729.

So we should should configure them as -

connect: {
  server: {
    options: {
      port: 8000,
      hostname: 'localhost',
      livereload: 35729
    }
  }
},
watch: {
  options: {
    livereload: 35729
  },
  files: ['**'],
  tasks: []
}

You need not provide "connect" as a task here. As the work of reloading is done by livereload here. Now to make these two work with a single command we will register them as -

grunt.registerTask("server", ["connect", "watch"]);

Now the connect is run and then watch is run. Now normally registerTasks works by finishing the first task then the second task and so on. But due to the behaviour of connect as stated by you -

Note that this server only runs as long as grunt is running

Connect is run only once. But watch will keep on running looking for changes (keeping grunt running) and thus keeping the connect server up.

Now when you try

grunt server

things will work like a charm.