Day 7: GruntJS LiveReload–Take Productivity to the Next Level

On day 5 of my 30 technologies in 30 days challenge I talked about using GruntJS to perform repetitive tasks. Today, we will extend the example covered in that blog with HTML templates and the livereload server. In this blog, we will first cover how we can use an HTML template with the grunt-markdown plugin and then I will cover how we can take productivity to the next level by using the grunt-watch plugin. Please read my earlier blog on GruntJS in case you are not familiar with GruntJS.

Pocket watch saving time with OpenShift and GuntJS picture

Github repository

The code for today’s demo application is available on github: day7-gruntjs-livereload-example.

Using templates with the GruntJS Markdown plugin

In my last blog on GruntJS (see above), I talked about how we can convert a Markdown document to an HTML document using the grunt-markdown plugin. In most cases, we would also like to css styling for the HTML document. To make my blog posts look good, I decided to use Twitter Bootstrap to style the HTML documents. This requires us to specify the HTMTL template which grunt-markdown plugin should use and is a fairly easy process by specifying the template using the template configuration option.

markdown: {
    all: {
      files: [
        {
          expand: true,
          src: '*.md',
          dest: 'docs/html/',
          ext: '.html'
        }
      ],
      options: {
        template: 'templates/index.html',
        markdownOptions: {
          gfm: true,
          codeLines: {
            before: '<span>',
            after: '</span>'
          }
        }
      }
    }
  },

The template/index.html looks like as shown below.

<!DOCTYPE html>
<html>
<head>
    <title>Learn 30 Technologies in 30 Days</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="../../css/bootstrap.css" media="screen">
  <style type="text/css">
    body {
      padding-top:60px;
      padding-bottom: 60px;
    }
  </style>
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">30 Technologies in 30 Days</a>
        </div>
 
    </div>
  </div>
 
    <div id="main" class="container">
        <%=content%>
    </div>
 
</body>
</html>

The <%=content%> will be replace by Markdown HTML document.

We can look at the generated HTML 5 document by running the grunt command again.

grunt

The HTML 5 document will be generated in the docs/html folder.

Watch my back

One of the core plugins of GruntJS is grunt-contrib-watch. The plugin can run in the background and watch for any changes in the configured resources. To install grunt-contrib-watch plugin, we have to use following npm command.

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

The command shown above will update the dev dependencies in package.json file.

{
  "name": "blog",
  "version": "0.0.0",
  "description": "My awesome blog",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-uglify": "~0.2.5",
    "grunt-markdown": "~0.4.0",
    "grunt-contrib-watch": "~0.5.3"
  }
}

As with every plugin, the next task is to configure the plugin in Gruntfile.js. To do this, add the following to grunt’s initConfig method. This ensures whenever there is a change in any of these files it will update run the uglify and markdown tasks.

watch :{
    scripts :{
      files : ['js/app.js','*.md','css/*.css'],
      tasks : ['uglify','markdown']
    }
  }

Next load the watch task by adding this line to Gruntfile.

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

In order to invoke the Grunt watch task, just run the grunt watch command.

$ grunt watch
Running "watch" task
Waiting...

Now we can change the app.js file in the js folder. Add the following function to app.js.

function goodNight(name){
    return "Good Night, " + name;
}

As soon as we add the function, Grunt watch task will run both the uglify and markdown tasks.

$ grunt watch
Running "watch" task
Waiting...OK
>> File "js/app.js" changed.
 
Running "uglify:build" (uglify) task
File "js/app.min.js" created.
 
Running "markdown:all" (markdown) task
File "docs/html/day1.html" created.
 
Done, without errors.
Completed in 0.580s at Sun Nov 03 2013 00:15:54 GMT+0530 (IST) - Waiting...

We can see the updated app.min.js file to confirm the changes.

function hello(a){return"Hello, "+a+"! How are you?"}function bye(a){return"Bye, "+a}function goodNight(a){return"Good Night, "+a}

Similarly, if we make a change to the Markdown file, then a new HTML document will get created.

Can we do better? Yes, use livereload

One of the featuress of the GruntJS watch plugin is that it can automatically reload changes. It is very helpful if we are making style changes and want to get instant feedback without pressing the browser refresh button. To use livereload, replace the watch plugin configuration with the one mentioned below.

watch :{
    scripts :{
      files : ['js/app.js','*.md','css/*.css'],
      tasks : ['uglify','markdown'],
      options : {
        livereload : true
      }
    }
  }

This will start the server at http://localhost:35729/. We can change the port number by updating the configuration.

watch :{
    scripts :{
      files : ['js/app.js','*.md','css/*.css'],
      tasks : ['uglify','markdown'],
      options : {
        livereload : 9090,
      }
    }
  }

Now restart the server, and it will be available at http://localhost:9090/.

To enable live reloading, we need tot add <script src="http://localhost:9090/livereload.js"></script> to the templates/index.html file.

Restart the server, and make some change to bootstrap.css. Change the

.navbar-inverse {
  background-color: #222222;
  border-color: #080808;
}

to

.navbar-inverse {
  background-color: red;
  border-color: #080808;
}

We will immediately see the change in docs/html/day1.html file.

That is it for today. Keep the feedback coming.

Next Steps

Categories
Node.js
Tags
,
Comments are closed.