Moving from CodeKit to Grunt Watch + LiveReload for Real-time JavaScript/LESS/SASS Compilation

Grunt Logo

Let me start by saying that I’m a big fan of CodeKit. It’s served me well for years and I continue to use it on many of my projects. With that said, I’ve found myself doing lots of Node.js development lately and have been using Grunt for various building tasks. Grunt is a task runner that has a ton of packages for doing things like compiling LESS/SASS into CSS, concatenating JavaScript, minifying, etc. It also has a package for watching files (the same way CodeKit does) and firing off certain tasks when they’re modified.

Given that Grunt has these features, once it’s integrated into a project, it makes sense to leverage it for the real-time compiling and reloading of JS/LESS/SASS files. You’ll be able to reuse many of the same build tasks and it’ll allow other developers (who may not have CodeKit installed) to easily follow the same workflow when they open your project. Here’s how to do it.


Suppose we have a project using JavaScript and LESS. The file structure looks like this:

/javascript
  /jquery.js
  /functions.js
  /app.js
/less
  /_header.less
  /_footer.less
  /_body.less
  /style.less
/public
  /css
    /style.css
  /js
    /main.min.js

We have 3 JavaScript files in the /javascript directory that need to be combined and minified into /public/js/main.min.js. We also have a style.less file (that imports the other underscored .less files) and compiles down into /public/css/style.css. Simple enough.

In CodeKit, you’d drag this whole folder into your window. You’d configure some options and set the output paths, then you’d be good to go. CodeKit would start watching the files and automatically recompile.

In Grunt, however, we need to explain these procedures via a configuration file. Don’t worry. It’s easy! Here’s what you need to do.

(Note: I know this seems like a lot of steps, but often times many of them are done already — especially if you’re working on a Node.js project)


1. Install Node.js (with NPM)

Even if your project isn’t written in Node.js, you’ll need it to access these tool. Just go to nodejs.org and grab the latest copy. This will also install NPM (the Node.js Package Manager).

2. Install Grunt

Because you’ll be using Grunt a lot, it’s easiest to just install it globally. You can do that by running this command:

sudo npm install -g grunt-cli

(After the installation is complete, you may need to exit your terminal window and reopen it again to gain access to the “grunt” command.)

3. Configure NPM’s package.json with Grunt Plugins

Ok, NPM is installed. Now we need to configure the necessary packages so that all the Grunt plugins we need will be downloaded. You’ll need to create a package.json file with the contents below. If this file already exists, just add the entries in the dependencies section.

{
  "name": "my-project-name",
  "version": "0.0.1",
  "dependencies": {
    "grunt-cli": "latest",
    "grunt-contrib-concat": "latest",
    "grunt-contrib-uglify": "latest",
    "grunt-contrib-less": "latest",
    "grunt-contrib-watch": "latest"
  }
}

4. Install Grunt Plugins via NPM

Now that we’ve configured our package.json file with the packages we need, let’s install them.

npm install

This will download all the packages we specified above and place them into the node_modules directory in your project’s root.

5. Configure Gruntfile.js

Ok, everything is installed. The last thing we need to do is setup Grunt’s configuration file.

module.exports = function(grunt) {

  grunt.registerTask('watch', [ 'watch' ]);

  grunt.initConfig({
    concat: {
      js: {
        options: {
          separator: ';'
        },
        src: [
          'javascript/*.js'
        ],
        dest: 'public/js/main.min.js'
      }, 
    },
    uglify: {
      options: {
        mangle: false
      },
      js: {
        files: {
          'public/js/main.min.js': ['public/js/main.min.js']
        }
      }
    },
    less: {
      style: {
        files: {
          "public/css/style.css": "less/style.less"
        }
      }
    },
    watch: {
      js: {
        files: ['javascript/*.js'],
        tasks: ['concat:js', 'uglify:js'],
        options: {
          livereload: true,
        }
      },
      css: {
        files: ['less/*.less'],
        tasks: ['less:style'],
        options: {
          livereload: true,
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');

};

This configuration file setups up a number of tasks for concatenating, compiling and minimizing the JS and LESS. It also tells Grunt to execute the tasks anytime the files are modified.

6. Run Grunt Command to Watch Your Files

Now that everything is downloaded and configured, we simply need to run a single command to make Grunt start watching our files.

grunt watch

Run this command (in your project’s root directory) anytime you want Grunt to start watching your files. To stop the process, simply use control + c on your keyboard.


You’ll notice that there are a few livereload flags in the Grunt configuration file above. This tells Grunt to alert LiveReload that files have changed so that it can automatically refresh your browser window. For this functionality to work, you can purchase LiveReload or just install the free LiveReload Chrome Extension. (Make sure it’s enabled by clicking the icon in your browser’s toolbar.)


That’s everything you need to get started! Please note that if your files are structured or named differently, you may need to adjust the configuration above. Also note that Grunt has a huge library of plugins that do much more than what’s show here, so take a look and poke around.


Note: If enjoyed using Grunt above, check out my articles on Grunt deployment and Grunt + Bower for WordPress Themes.