What is Grunt?

July 9, 2014

Grunt (logo) Simply put, Grunt is a JavaScript task runner created to implement the many repetitive tasks most developers have to do everyday. It can range from compiling, concatenating, minifying files or even building out template partials. The options are nearly endless.

I’ve been using Grunt to compile Sass to CSS for about nine months now and it has become part of my daily workflow.

Tools Used Before Using Grunt

My go-to app for Sass to CSS compiling was Livereload: I could simply point a theme directory to it and never have to think about it again.

The browser I like best for front-end development is Firefox. It's the best implementation of Firebug and its own developer tools have improved greatly in the latest releases. Additionally, the Livereload developer created a Firefox add-on that talks to the Livereload app and refreshed my browser each time I did a save.

Apple released Mountain Lion 10.8 in July of 2012 and, being the early adopter that I am, I installed it as soon as I received a copy.

And then it happened: I lost Livereload.

From that point on, Livereload would throw an error every time I saved a SASS file. Looking back, I believe there was a conflict between my system Ruby/gems and the gems built in Livereload.

Moving forward, I switched to Codekit (version 1 at the time), which also worked very well. But still, I was without the browser auto-refresh in Firefox. I thought about switching my developement browser to Chrome so the refresh would work via Codekit’s Applescript, but I still relied heavily on Firebug.

Discovering Grunt

Last fall I read a 24 Ways post by Chris Coyier titled, "Grunt for People Who Think Things Like Grunt are Weird and Hard."

Having only heard about Grunt at the time, and knowing how well Chris writes, I was intrigued. What stood out to me most in the article was how easy it is to set up Grunt. Additionally, the flexibility and options provided are endless.

Needless to say, I quickly fell in love with Grunt and all that it can do. It currently has more than 3,000 contributed npm (node package modules) plugins, and the list keeps growing.

Using Grunt to Compile, Check my Code, and Notify

My Grunt workflow is very simple. Given that most of my theming is done for the Drupal CMS, I don’t need to concatenate or minify my files. Drupal will handle that for me once it’s in production mode.

So, when building out a sub theme, I typically rely on 5 npm Grunt plugins:

1) grunt
Well of course — can’t do much without it.

2) grunt-contrib-compass
I use the Zen base theme for all my Drupal projects. Zen uses the Compass Sass framework of shared mixins and executable compiler.

3) grunt-contrib-jshint
Need this to make sure I’m writing correct jQuery. It alerts me when it finds an error by providing the line number, column number, and filename along with suggested fixes.

4) grunt-contrib-watch
This is my Livereload replacement. It keeps an eye on my designated files and alerts Grunt when I make a change and save a file. When that happens, watch tells Grunt to run through all my tasks again.

5) grunt-notify
I use this in conjunction with grunt-contrib-watch. Everytime Grunt runs a tasks and either completes it successfully or finds an error, grunt-notify will let me know.

Only Two Files Needed

To start, I place the 'package.json' and 'Gruntfile.js' files in my theme directory.

package.json

{ "name": "DesignHammer", "version": "0.1.0", "devDependencies": { "grunt": "latest", "grunt-contrib-compass": "latest", "grunt-contrib-jshint": "latest", "grunt-contrib-watch": "latest", "grunt-notify": "latest" } }

Gruntfile.js

module.exports = function(grunt) { 'use strict';

// Project configuration grunt.initConfig({ pkg: grunt.file.readJSON('package.json'),

compass: {
  dist: {
    options: {
      sassDir: 'sass',
      cssDir: 'css'
    }
  }
},

jshint: {
  src: ['js/*.js']
},

watch: {
  options: {
    livereload: true
  },
  sass: {
    files: ['sass/*.scss', 'sass/**/*.scss'],
    tasks: ['compass', 'notify:sass'],
    options: {
      livereload: false
    },
  },
  js: {
    files: ['js/*.js'],
    tasks: ['jshint', 'notify:js']
  },
  css: {
    files: ['css/*.css']
  },
},

notify: {
  js: {
    options: {
      title: 'Task Complete',  // optional
      message: 'JSHint finished, no errors!' //required
    }
  },
  sass: {
    options: {
      title: 'Task Complete',  // optional
      message: 'SASS/Compass finished compiling!' //required
    }
  },
}

}); // end jSON

// Load plugins grunt.loadNpmTasks('grunt-contrib-compass'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-notify');

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

};

Next, I open my theme directory in Terminal app (by cmd + drag the theme folder to Terminal window) and type npm install. This installs all the node_modules I have listed in the package.json file.

Once that is done, type grunt and you're tasking away.