Beginners Guide to Grunt

I put off checking out GruntJS far to long. I was prefectly fine using CodeKit. It’s a great piece of software and did everything I needed it to do. About a year ago I ran into an issue. Someone else on the team needed to compile assets and didn’t have CodeKit. We needed a way for them to compile the assets just as I had been doing, with the same settings etc. This is when I started to look into GruntJS. My workflow has changed for the better ever since.

Why GruntJS

For me personally the biggest advantage of using GruntJS (or similar) is the ablity for everyone on the team to compile the assets with the same settings. I can include my GruntJS config file right into my project folder and push it up to our shared repositoty. Not to undermine the other awesome stuff you can do with GruntJS, that I could have never done with just CodeKit.

My Grunt Workflow

I have a pretty simple Grunt workflow. Sass with Compass to compile CSS, Uglify to concatenate and minify my javascript files. Then to make all this happen while I’m developing I use GruntWatch. This allows me to save my files, and trigger Grunt to compile my assets. I then have LiveReload setup to refresh my browser when changes occur in my project. For the past year or so I’ve been working with this workflow, and it has been pretty sweet.

Getting Started with GruntJS

I’d like to first say that GruntJS itself has a great getting started guide. It helped me get started as well as Chris Coyier video tutorial on Grunt.

Install NodeJS

GruntJS is built on NodeJS so you will need to install this before anything else. Go to NodeJS.org, there is a big green Install button.

Install GruntJS

Now that you have NodeJS installed lets actually install the GruntJS cli. This will allow us to run our grunt commands from the command line.

We install this through the Nodes npm package manager. So open up a new terminal window and run the following command.

npm install -g grunt-cli

You might have to add sudo to the beginning of this command if you run into permission issues

Setting Up Package.json File

Open your project in your code editor and create a new file named package.json. Open this file and paste the jSON below into it.

{
  "name": "project-name",
  "version": "1.0.0",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-uglify": "~0.5.0",
    "grunt-contrib-compass": "^1.0.1",
    "grunt-contrib-watch": "^0.6.1"
  }
}

Here you will need to fill in project-name” with your project’s name. In the devDependencies section, this is the plugins that I use with Grunt. For me this is my standard package.json file. If you want to add more plugins to your workflow you would add them here.

Save that file then jump back to terminal and browse to your projects folder. For me on Mac that looks something like this.

cd ~/Projects/project-name

Once you browse to your project folder run the following command to install Grunt and all of our plugins into our project.

npm install

Just like the command above you might have to add sudo to the beginning of this if you run into permission issues.

Gruntfile.js

Now that we have GruntJS setup and all of our plugins ready to go, lets tell Grunt what we want it to do. We do this using the Gruntfile.js. So go ahead and create this file in your projects folder.

We communicate to Grunt through the module.exports method. So we will put all of our config for Grunt within this function.

module.exports = function(grunt) {
};

Your Gruntfile will have three sections, config, load, register.

Config - This is where we tell each grunt plugin our settings we want it to use. So for example we need to tell the Sass plugin where our Sass files are and where we want it to output our CSS to.

grunt.initConfig({
    compass: {
      dist: {
        options: {
          sassDir: 'public/scss',
          cssDir: 'public/css/build',
          outputStyle: 'compressed'
        }
      }
    },
});

Load - Here we load each indivual plugin into the environment. This tells grunt to load each defined plugin. Without this step we wont be able to use a specific plugin, unless we tell Grunt we want it loaded.

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

Register - This is where we register additional commands. So we can register a compass command(task). This would allow us to run grunt compass, and Grunt would then run our compass fast and compile our Sass files using compass. We always start off with registering the default grunt no matter what.

grunt.registerTask('default', ['uglify','compass','watch']);

When we put it all together into a single Gruntfile it looks something like this.

module.exports = function(grunt) {

  // Project configuration
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    uglify: {
      build: {
        src: ['public/js/lib/*.js','public/js/app.js'],
        dest: 'public/js/build/app.min.js'
      }
    },
    compass: {
      dist: {
        options: {
          sassDir: 'public/scss',
          cssDir: 'public/css/build',
          outputStyle: 'compressed'
        }
      }
    },

    watch: {
      scripts: {
        files: ['public/js/*.js','public/js/lib/*.js'],
        tasks: ['uglify'],
        options: {
          spawn: false,
        },
      },
      css: {
        files: ['public/scss/*.scss','public/scss/partials/*.scss'],
        tasks: ['compass'],
        options: {
          spawn: false,
        },
      },
    },

  });

  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Default task(s)
  grunt.registerTask('default', ['uglify','compass','watch']);

};

Each plugin for Grunt has its own settings that you can set. You will need to change the file paths in the config above before it will work for your project.

Once you have everything setup and your config file is ready to go. Go back to your terminal window and run grunt. This will cause grunt watch to start running. Now when you change your CSS or JS files and save, grunt will run the compass and uglify plugins to compile your assets.

Here are the plugins that I’m using in my Grunt workflow. You can read more about settings for each plugin on their GitHub pages.

https://github.com/gruntjs/grunt-contrib-compass https://github.com/gruntjs/grunt-contrib-uglify https://github.com/gruntjs/grunt-contrib-watch