Pages

Wednesday, June 4, 2014

Live reload with grunt-express and grunt-contrib-watch


Making frequent changes to your static content and constantly refreshing your browser to see them take effect can get frustrating at times and sometimes the cache plays a party pooper. If your project uses grunt then can configure it to set up live reload of your changes to your browser. You can set up a watch task that constantly monitors your files for any changes and when it detects a change, it publishes it and refreshes your browser automagically. You can try this bare minimum Gruntfile.js configuration required to setup live reload using 'grunt-express' and 'grunt-contrib-watch'.

Make sure you have 'grunt-express' and  'grunt-contrib-watch' plugins installed locally in your project. Use the 'save-dev' option to save these as your dev dependencies in your package.json

> npm install grunt-express --save-dev

> npm install grunt-contrib-watch --save-dev

Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({
    pkg: grunt.file.readJSON( 'package.json' ),
  
    express: {
      server : {
        options : {
          port : 9001,
          hostname : '*',
          bases : ['.'], 
          livereload : true
        }
      }
    },
    watch : {
      options : {
        livereload : true
      }
    }
  });

  grunt.loadNpmTasks( 'grunt-contrib-watch' );
  grunt.loadNpmTasks( 'grunt-express' );

  grunt.registerTask('server', ['express:server', 'watch']);
}

The default port for express is 3000, but you can specify your own and it will serve your requests on it provided it is not being used by some other process.

For the hostname option, specifying ‘0.0.0.0’, ‘127.0.0.1’, ‘localhost’ or ‘*’, all worked for me and I was able to access the app from both ‘127.0.0.1’ and ‘localhost’, in all the 4 cases. So use any.

Use relative or absolute paths for your bases array, which is an array of locations from where all static content of your app will be served. In case the relative paths do not work, you can try to use node's path module to resolve your relative paths. Just use require to get an instance of it on top of your gruntfile somewhere and you'll be all set.

// Somewhere on top of your gruntfile
var path = require('path');

// Inside express' options config
bases : [path.resolve('.')]

Set livereload to true in both express and watch config.

Now note that the express task will end as soon as all tasks have been performed, so your express server will die immediately. To keep it running you can either use 'express-keepalive' task along with the 'express' task on the terminal with the 'grunt' command:-

> grunt express:server express-keepalive

Or you can register a custom task in the gruntfile with these two as follows:-

grunt.registerTask('server', ['express:server', 'express-keepalive']);

But whats nice is that the watch task keeps on running, so if you use it after the express task, it will basically keep the express server on. And that is what we have done in this example. 'grunt-parallel' plugin is another good option you can check that can help run these tasks in parallel and you can throw in 'express-keepalive' in there to keep your server on.

No comments:

Post a Comment