Edit: check version information. grunt-contrib-watch liver support is now supported.
What a doozy. I ran into problems with this, so let me do my best to explain (or at least run you). Keep in mind that this is how I configure and it seems to work most of the time.
First you need to make sure that you have tricked your package.json with the correct dependencies. I'm not sure that working with the liver works with the task baked in the “clock”, and I have been using grunt-regarde recently. My .json package usually looks like this:
"dependencies": { "grunt": "~0.4.x", "grunt-contrib-livereload": "0.1.2", "grunt-contrib-connect": "0.2.0", "grunt-regarde": "0.1.1" },
Obvi you want grunt (duhhh), livereload, connect seems to help with installation folders, and this is similar to grunt-watch, it just seems to work better (I forgot why).
You could make your package.json even better by specifying the load function in your own devDependencies function if you are so inclined. Now run your good old fasioned npm install to get the goodies in your project.
Speak gruntfiles:
As you probably know, the grunt file does the magic. Somewhere at the bottom of your grunt file you need to specify
grunt.loadNpmTasks('grunt-regarde'); grunt.loadNpmTasks('grunt-contrib-livereload'); grunt.loadNpmTasks('grunt-contrib-connect');
At the top of your grunt file, we will want to add some utilities to load into the file. In the /*global module:false*/ section, navigate and add var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet; .
After that, you really don't need to learn the connection, you just have to use it. Check out my style:
var folderMount = function folderMount(connect, point) { return connect.static(path.resolve(point)); };
This happens before module.exports = function(grunt) {
Now let me go into the meat of the grunt file. Again, I forget what the connection does, but this is where the magic of middleware begins. In your modules.exports add:
connect: { livereload: { options: { port: 9999, middleware: function(connect, options) { return [lrSnippet, folderMount(connect, '.')] } } } },
Now we want the files to be viewed. I like to set up several different tasks, because I don’t want the whole rooting process to be performed every time I save the CSS file. Here's what I'm working with (add to module.exports ):
regarde: { txt: { files: ['styles/*.css', 'index.html'], tasks: ['livereload'] }, styles: { files: ['sass/*.scss', 'sass/*/*.scss'], tasks: ['compass'] }, templates: { files: ['templates/*.jade'], tasks: ['jade'] } },
You can see that I only need to shoot from the list if changes have been made to my compiled css ( *.css ) or to my compiled html. If I edit the SCSS file, I want to disable only the compass. If I edit a jade template, I only want to run jade in the HTML compiler. I think you can see what is happening. You can play with it, just be smart, because you can get into an endless cycle.
Finally, you need to hide these processes. I like to connect them all with my main task, because my gruntfile is just cute.
// Default task. grunt.registerTask('default', ['livereload-start', 'connect', 'regarde']);
Now, when you run grunt in the CLI, you should (hopefully cross your fingers) get something like this:
Running "connect:livereload" (connect) task Starting connect web server on localhost:9999.
Go to http://localhost:9999/yourpage.html and see how the magic happens.
full grunt file here full package.json here.