Speed Up Your Web Development Workflow with Grunt

Jul 24 2013 by Ben Briggs | 9 Comments

Speed Up Your Web Development Workflow with Grunt

In a series of tutorials, I’m going to help you get started with Grunt, an open source JavaScript task runner that will automate some of your web development tasks.

This nifty JavaScript library will notably speed up and improve your web development processes, and also help you sidestep common human errors.

My intention with this Grunt tutorial series is to get you to experience the same productivity and efficiency improvements I’ve gained through this useful, but little-known open source JavaScript tool.

Here’s the outline of this three-part Grunt tutorial series:

  1. Speed Up Your Web Development Workflow with Grunt: We’ll cover basic information about Grunt; what Grunt is, how to install Grunt, how to use Grunt in your web projects, and a brief overview of gruntplugins.
  2. Create a test project using modern front-end development techniques (will be posted on a later date)
  3. Using Grunt and Jasmine to automate testing and enforce code quality (will be posted on a later date)

Let’s start this tutorial series with some basic information about Grunt and how it can help speed up your web development workflow.

What is Grunt?

When I started my job as a front-end web developer at CDNify (we’re a content delivery network aimed at web developers, startups, and digital agencies) I had absolutely no idea what Grunt was or how it could significantly improve my development workflow.

Months down the road, and I’m now using Grunt every single day. I can’t imagine my front-end web development workflow without it now.

In short, Grunt is an open source JavaScript project that automates repetitive tasks you often have to do as a web developer.

Grunt can automate tasks like minification, unit testing, and preparing your files and website assets for production use. Grunt does this by wrapping these processes up into tasks.

A few more examples of common Grunt tasks are:

  • Optimizing your web images through a service like Smush.it
  • Concatenating JavaScript files into one big file for faster web page load times
  • Running scripts that analyze your code for potential errors (often referred to as linting)
  • Enforcing your coding style guides for uniformity and readability throughout your project’s code base
  • Compiling your CSS from LESS/Sass

Anything that has the potential to be automated can be done with Grunt.

You can configure Grunt to watch certain files for changes, and then build the results on the fly.

Using Grunt in Your Web Development Team

When used in a team environment, Grunt can help every person in that team write code that adheres to the same standards/style guides.

Details such as controlling the indentation of code can now be a strict process, as a whole build will fail if any part throws an error.

For example, when indenting code, you could automatically enforce the use of spaces instead of tabs (or vice versa, depending on your preferences), which will ensure that the whole team has the same configuration. When they push code to the repository, it’s in the expected format.

Used in conjunction with your favorite code-quality tools (for example, JSHint), Grunt will help you catch sloppy code such as missing semicolons, braceless control statements, unused variables, and trailing whitespace. This is excellent for discovering human errors as well as disallowing valid, but badly written, JavaScript.

Prerequisites

To get the most out of Grunt, you should first know (or learn about) the following.

Command-line Interface

In order to use a tool such as Grunt effectively, you will need to have at least a basic understanding of the terminal. You’ll need to be familiar with the command line interface (CLI) for the file system you use.

You should be able to navigate confidently to a folder on your system and run commands within it.

Here are tutorials and resources that will get you started on learning how to use CLIs on your own computer:

However, note that you’ll need to be familiar with the CLI of the SSH client you use to connect to your remote web server if you want to use Grunt on web projects. One popular SSH client for Windows and Linux is PuTTY. (Learn how to use PuTTY by reading its docs).

Don’t be put off; you’ll see that the CLI is very simple once you start using it. It’s also a very powerful tool, and knowing how to use it effectively can speed up your workflow on its own.

Optional: Version Control System

Although not technically required in order to use Grunt, Grunt works best in an environment where version control is important.

Using Grunt for a small static website that is likely to be updated infrequently may be considered overkill. Any web development project that’s larger than that should be version-controlled. And large web development projects are where Grunt becomes critical and extremely useful.

Read this list of Git tutorials for beginners or this introductory guide to Git to help you get started with Git, a popular version control system.

Get Started with Grunt

I’ll run through the general steps of installing Grunt, which is a process that relies on Node.js (an open source development platform for network applications).

Install Node.js

In order to install Grunt, Node.js must first be installed or available in your dev environment (which could your computer) or your web server.

Currently, Node.js version 0.8.0 and up is the supported version.

Download and install Node.js by first going to:

The official Node.js Download Page has various options for you, such as a Windows installer, a Mac OS installer, Linux binaries, and the source code.

If you need help installing Node.js, read the following tutorial:

Installing Node.js allows us to install Grunt using Node.js’s package manager, called npm.

Install Grunt

Next, you need to install Grunt and its dependencies. We will install Grunt using Node.js’s npm.

Learn how to install Grunt with npm by reading this tutorial:

Install Grunt’s Command Line Interface (CLI)

Grunt’s Command Line Interface (CLI) allows you to run Grunt in any directory.

We can install Grunt’s CLI with this npm command:

npm install -g grunt-cli

You may need to prefix the command with sudo on OS X, *nix, BSD, etc., or run your command shell as Adminstrator on Windows to install Grunt’s CLI.

Note that installing the CLI doesn’t install the Grunt task runner itself, as each project may wish to use a different version of Grunt. (In this tutorial, we’ll be using Grunt 0.4x.)

Instead, the CLI acts as a bridge between your Gruntfile (more on this in a bit) and the version of Grunt installed locally to your project.

Using Grunt in a Web Development Project

Now that you have Grunt installed, let’s go over the basics of how to use it in a web development project.

To use Grunt in a web development project, we need two files: package.json and a Gruntfile (e.g. Gruntfile.js).

package.json

package.json is a JSON file. This file should be located in your project’s root directory.

Project information and settings are specified in package.json, such as the project name, version, author, and if it’s a private project or not.

package.json also contains what are known in the Node.js nomenclature as devDependencies. devDependencies are items you need for your project. In this sense, Grunt will be an item listed under devDependencies, along with the Grunt plugins you want to use for the project (I’ll talk about this later).

Here’s an example template for a package.json file:

{
	"name" : "Project Name",
	"version" : "version number",
	"author" : "Your Name",
	"private" : true,

"devDependencies" : { "grunt" : "~0.4.0" } }

By specifying the project’s dependencies in package.json, we can use npm to install them for us automatically simply by running the following command in our project’s directory:

npm install

Running that command will give us an output like this:

	npm http GET https://registry.npmjs.org/grunt
	npm http 304 https://registry.npmjs.org/grunt
	npm http GET https://registry.npmjs.org/async
	npm http GET https://registry.npmjs.org/dateformat/1.0.2-1.2.3
	npm http GET https://registry.npmjs.org/colors
	npm http GET https://registry.npmjs.org/coffee-script
	npm http GET https://registry.npmjs.org/glob
	npm http GET https://registry.npmjs.org/iconv-lite
	npm http GET https://registry.npmjs.org/findup-sync
	npm http GET https://registry.npmjs.org/lodash
	npm http GET https://registry.npmjs.org/js-yaml
	npm http GET https://registry.npmjs.org/hooker
	npm http GET https://registry.npmjs.org/minimatch
	npm http GET https://registry.npmjs.org/nopt
	npm http GET https://registry.npmjs.org/which
	npm http GET https://registry.npmjs.org/rimraf
	npm http GET https://registry.npmjs.org/underscore.string
	npm http GET https://registry.npmjs.org/eventemitter2
	npm http 304 https://registry.npmjs.org/async
	npm http 304 https://registry.npmjs.org/dateformat/1.0.2-1.2.3
	npm http GET https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
	npm http 304 https://registry.npmjs.org/glob
	npm http 304 https://registry.npmjs.org/colors
	npm http 304 https://registry.npmjs.org/iconv-lite
	npm http 304 https://registry.npmjs.org/findup-sync
	npm http 304 https://registry.npmjs.org/lodash
	npm http 304 https://registry.npmjs.org/js-yaml
	npm http 304 https://registry.npmjs.org/hooker
	npm http 304 https://registry.npmjs.org/minimatch
	npm http 304 https://registry.npmjs.org/which
	npm http 304 https://registry.npmjs.org/rimraf
	npm http 304 https://registry.npmjs.org/underscore.string
	npm http 200 https://registry.npmjs.org/coffee-script
	npm http 304 https://registry.npmjs.org/eventemitter2
	npm http 200 https://registry.npmjs.org/nopt
	npm http 200 https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
	npm http GET https://registry.npmjs.org/graceful-fs
	npm http GET https://registry.npmjs.org/abbrev
	npm http GET https://registry.npmjs.org/sigmund
	npm http GET https://registry.npmjs.org/lru-cache
	npm http GET https://registry.npmjs.org/graceful-fs
	npm http GET https://registry.npmjs.org/inherits
	npm http GET https://registry.npmjs.org/argparse
	npm http GET https://registry.npmjs.org/esprima
	npm http 304 https://registry.npmjs.org/graceful-fs
	npm http 304 https://registry.npmjs.org/abbrev
	npm http 304 https://registry.npmjs.org/lru-cache
	npm http 304 https://registry.npmjs.org/graceful-fs
	npm http 304 https://registry.npmjs.org/sigmund
	npm http 304 https://registry.npmjs.org/inherits
	npm http 304 https://registry.npmjs.org/argparse
	npm http 304 https://registry.npmjs.org/esprima
	npm http GET https://registry.npmjs.org/underscore
	npm http 304 https://registry.npmjs.org/underscore
	grunt@0.4.1 node_modules/grunt
	├── which@1.0.5
	├── dateformat@1.0.2-1.2.3
	├── colors@0.6.0-1
	├── hooker@0.2.3
	├── async@0.1.22
	├── eventemitter2@0.4.12
	├── coffee-script@1.3.3
	├── underscore.string@2.2.1
	├── iconv-lite@0.2.11
	├── lodash@0.9.2
	├── findup-sync@0.1.2 (lodash@1.0.1)
	├── rimraf@2.0.3 (graceful-fs@1.1.14)
	├── nopt@1.0.10 (abbrev@1.0.4)
	├── minimatch@0.2.12 (sigmund@1.0.0, lru-cache@2.3.0)
	├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
	└── js-yaml@2.0.5 (esprima@1.0.3, argparse@0.1.15)

Gruntfile

The Gruntfile is the main configuration file for the project, and specifies what tasks Grunt should run and what files in the project they affect.

Your project’s Gruntfile can be a JavaScript file (Gruntfile.js) or CoffeeScript file (Gruntfile.coffee).

In this tutorial, we’ll be using JavaScript.

At its most basic form, the Gruntfile should contain the following:

module.exports = function(grunt){
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json')
	});
	
	grunt.registerTask('default', []);
};

initConfig is where the dependency options are specified. Each Grunt plugin is configured using a JSON object (with some exceptions).

Some plugins allow more than one configuration to be loaded. For example, there may be a specific set of experimental JavaScript that uses a different library to jQuery, and so that library must be predefined instead of jQuery in the JSHint configuration. (We will look at this in more detail in the third part of this Grunt tutorial series.)

registerTask can be specified more than once. The default task is run when Grunt is executed in the command line, and so this should contain common setup tasks.

At this point, if you run Grunt successfully, it will generate the following output:

Done, without errors.

Now we have a project skeleton which will become useful once we use some plugins.

Using Grunt Plugins

A key feature of Grunt is the use of Grunt plugins. Grunt plugins are referred to as gruntplugins in the Grunt nomenclature.

gruntplugins are user-contributed modules that will help you automate tasks without having to write your own task scripts.

For example, you can use the grunt-contrib-compress gruntplugin to compress and optimize the file sizes of your project files.

To use the plugin in a project, these are the steps to take:

  1. List it as a devDependency object in package.json
  2. Load it using the loadNpmTasks function in the project’s Gruntfile
  3. Register the task by using the registerTask function in the project’s Gruntfile
  4. Run npm install to install Grunt and the plugin

Here’s the sample source code for using the grunt-contrib-compress gruntplugin in your project.

package.json

{
	"name" : "My Sample Project",
	"version" : "1.0",
	"author" : " Ben Briggs",
	"private" : true,

	"devDependencies" : {
		"grunt" : "~0.4.0",
		"grunt-contrib-compress" : "~0.5.2"
	}
}

Gruntfile

module.exports = function(grunt){
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json')
	});

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

	grunt.registerTask('default', [compress]);
};

Grunt plugins are actually just npm modules that follow the gruntplugin template. You can find gruntplugins on the npm registry by browsing modules tagged with "gruntplugin" or at the official Grunt Plugins page. There are currently over 300 listed gruntplugins.

Summary

In this tutorial, this is what we covered:

  1. What Grunt is, and how it can help web developers speed up their workflow.
  2. Installation of Node.js
  3. Installation of Grunt
  4. Installation of Grunt’s CLI
  5. General usage of Grunt in web development projects
  6. How to use a gruntplugin

In the next tutorial in this Grunt tutorial series, we will go hands-on and apply what we’ve discussed here by creating a simple project using modern front-end development techniques paired with Grunt.

This is the three-part Grunt tutorial series outline:

  1. Speed Up Your Web Development Workflow with Grunt
  2. Create a test project using modern front-end development techniques (will be posted on a later date)
  3. Using Grunt and Jasmine to automate testing and enforce code quality (will be posted on a later date)

To ensure that you get notified when the next parts of this tutorial series is published, follow @sixrevisions on Twitter and/or Like the Six Revisions Facebook page.

Related Content

About the Author

Ben Briggs is a front-end developer at CDNify, a content delivery network designed for startups and developers. He’s passionate about modular CSS, preprocessors and optimization. Find Ben on Twitter: @ben_eb.

9 Comments

Prathap

July 25th, 2013

Ben, thank you for the introduction part of Grunt.

PK Anane

July 26th, 2013

You say, “At this point, if you run Grunt successfully, it will generate the following output:” You did not say how exactly you run grunt. i.e. type “grunt” in the terminal..

Thanks.. eagerly waiting for the next installment

PK Anane

July 26th, 2013

Ben,

I get an error when I try to complete the tutorial. This occurs after making the compress additions to the grunt file. I don’t see where the compress variable added to the grunt.registerTask() is defined.

error shown below:

Loading “Gruntfile.js” tasks…ERROR
>> ReferenceError: compress is not defined
Warning: Task “default” not found. Use –force to continue.

Aborted due to warnings.

Thanks again for the tutorial

Yuraï

July 26th, 2013

Nice article, thanks ;-)

David Waterston

July 28th, 2013

This is one of the best introductions to Grunt that I’ve read so far – clear, pitched at just the right level and, unlike the official documentation, not bogged down with unnecessary and irrelevant detail.
I’m looking forward to reading the next two parts.

Ben Briggs

July 29th, 2013

PK Anane: To use the compress addition you will need to specify some options in a JSON object that’s passed to grunt.initConfig. I’m covering this further in part two, but for now you can have a look at the compress documentation on https://npmjs.org/package/grunt-contrib-compress

Thanks everyone for your kind words :-)

Brian

July 30th, 2013

You can add “matchdep” to your devDependencies allowing a line like this to load all your dependencies for you:

require(‘matchdep’).filterDev(‘grunt-*’).forEach(grunt.loadNpmTasks);

Ally

July 30th, 2013

hi- who developed Grunt and where on Earth did the name Grunt come from? Just curious..

jerralyn

July 30th, 2013

Wow. I would love to try this Grunt. Thank you for your tutorial.

Leave a Comment

Subscribe to the comments on this article.