Getting Started with Grunt

A guest post by Domenic Denicola, who works on web apps as a consultant at Lab49 in New York City, while in his spare time maintaining many open-source Node.js and web libraries. He’s recently been involved in building better standards for the web and for JavaScript as a whole, such as the Promises/A+ specification, the ES6 promises spec, and the work-in-progress WHATWG streams specification, and can be reached at @domenic.

As web developers, we do certain tasks repetitively. Some of these are simple development tasks: things like linting your code or running unit tests. Others are important to do before deploying your site, or when assembling a final package for deployment: minifying your JavaScript and concatenating your CSS. Still others are important in both contexts, like browserifying your code so you can transform your source module files into something the browser can consume.

The approach we all start with is simply running these tasks manually, using the associated command-line tools at the appropriate times. This can be painful, particularly during development; the code/compile/lint/test/refresh cycle is not a fun one. Fortunately, tools have arisen to help automate this process, called task runners. A task runner allows you to control all of these tasks in a uniform way, and allows for the easy layering of functionality like watch mode or live reload on top of them.

The best task runner for the web development ecosystem is called Grunt. In this article, we’ll give you an overview of how to get started with Grunt for a simple web development workflow.

A Project Skeleton

To demonstrate the power of Grunt, we’re going to first need a project we can use it on. For now, we’ll create a very simple one: an index.html, and a lib/script.js file that logs things to the console. Our first task will be to get JSHint up and running with Grunt on this skeleton, before we branch out into getting Grunt to run our tests and the like.

Create a new directory, and add an index.html with this:

1

2

3

4

5

6

7

8

9

10

11

&lt;!DOCTYPE html&gt;

&lt;html&gt;

&lt;head&gt;

&lt;meta charset="utf-8"/&gt;

&lt;title&gt;Grunt Test!&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;p&gt;Check your console.&lt;/p&gt;

&lt;script src="lib/script.js"&gt;&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

Then create a directory inside that, called lib, and add a script.js there with this:

1

2

3

'use strict';

console.log('Hello, world!')

This will be enough to get us started.

Installing Prerequisites

Grunt, like most web development tools these days, runs on Node.js. You can install Node by going to their website and clicking the big “Install” button. Make sure it’s up and running like so:

1

2

$node--version

v0.10.22

Node also comes with npm, a JavaScript package manager that allows you to install things people have written in JavaScript — anything from command line tools, to server-side packages for Node.js, to client-side libraries for use in the browser. Check that you have it by running:

Adding Grunt to our Project

Grunt, like most JavaScript these days, works through npm. In turn, npm interfaces with your project via a special package.json file. So we need to create one! There are a few ways to do this, but since we just want to get started, let’s skip to the middle: copy this package.json into your project directory from before.

1

2

3

4

5

6

7

8

9

{

"name":"grunt-demo",

"description":"A demo web development project using Grunt",

"version":"1.0.0",

"devDependencies":{

"grunt":"~0.4.2",

"grunt-contrib-jshint":"~0.7.2"

}

}

The important part here is our devDependencies (“development dependencies”). To start off, we’ll be using Grunt itself, and the grunt-contrib-jshint plugin. (Later, we’ll add more Grunt plugins, but for now, let’s just try JSHint.) All of these things are distributed by npm, which understands the package.json file. Speaking of which, let’s tell npm to actually install these things now. Open your command prompt in the same directory as the package.json and type:

1

$npm install

This will generate lots of log messages, but in the end you should get a nice tree telling you what was installed. All those files go into the newly-created node_modules directory inside your project.

Creating a Gruntfile

Each project that uses Grunt has a Gruntfile specifying the plugins you’ll use, their configuration, and how they compose to create tasks. To get started, we’ll create a pretty basic Gruntfile. Copy these lines into a Gruntfile.js inside your project directory:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

'use strict';

module.exports=function(grunt){

grunt.loadNpmTasks('grunt-contrib-jshint');// (1)

grunt.initConfig({

jshint:{// (2)

files:['lib/**/*.js'],

options:{

devel:true,

globalstrict:true

}

}

});

grunt.registerTask('validate',['jshint']);// (3)

};

A few things are going on here:

At (1), we load the grunt-contrib-jshint plugin into Grunt.

At (2), we configure the options for the jshint task, which was supplied by the grunt-contrib-jshint plugin. The majority of Grunt tasks have a files option of some sort, and grunt-contrib-jshint is no exception. It has other options too, which you can see in its documentation grunt-contrib-jshint options. I usually use the jshintrc option so I can keep my JSHint settings in the usual .jshintrc file, but for now we’ll just set the options inline.

At (3), we create a new task, called validate, which currently just runs the jshint task. In the future, we’ll put our test-running task here too.

Running Your First Grunt Task

OK, let’s first make sure you’ve got everything set up right. You should have a setup like this:

1

2

3

4

5

6

7

8

├─┬lib

│└──script.js

├─┬node_modules

│├──grunt

│└──grunt-contrib-jshint

├──Gruntfile.js

├──index.html

└──package.json

If that looks right, then it’s time to give Grunt a try! Run the command grunt validate to run the validate task we set up earlier. You should get something like:

1

2

3

4

5

$grunt validate

Running"jshint:files"(jshint)task

&gt;&gt;1file lint free.

Done,without errors.

You can test that it is indeed linting your files by, for example, removing the semicolon from the end of the console.log line in lib/script.js. Then you’ll get:

1

2

3

4

5

6

7

8

9

$grunt validate

Running"jshint:files"(jshint)task

Linting lib/script.js...ERROR

[L3:C29]W033:Missing semicolon.

console.log('Hello, world!')

Warning:Task"jshint:files"failed.Use--force tocontinue.

Aborted due towarnings.

What Now?

Admittedly, getting JSHint running through Grunt is not that exciting by itself. You could have just run JSHint!

But the power of Grunt comes from leveraging multiple plugins in your project, and combining them into different tasks like validate versus deploy, or by composing plugins like grunt-contrib-watch to run tasks automatically in the background, or grunt-concurrent to run multiple tasks at the same time and speed up the process.

Safari Books Online has the content you need

Jasmine JavaScript Testing is a practical guide to a more sustainable JavaScript development process. You will learn by example how to drive the development of a web application using tests and best practices, and you’ll find a good section on Grunt.

Developing a Backbone.js Edge incorporates best practices and the techniques from the combined authors’ experience of developing many Backbone applications. Some of the resources on the web advocate inefficient or inelegant solutions and there are few that cover the whole library, and you’ll find a section on Grunt.

Eloquent JavaScript is a guide to JavaScript that focuses on good programming techniques rather than offering a mish-mash of cut-and-paste effects. The author teaches you how to leverage JavaScript’s grace and precision to write real browser-based applications. With clear examples and a focus on elegance, Eloquent JavaScript will have you fluent in the language of the web in no time.