The world of a front end developer is an ever changing one. New tools come out seemingly every day. So when I heard about this tool called Grunt, I went to go check out it's home page to learn what it was and how it could help me out. As soon as I saw that it used the commandline, it scared me away. With a background in design, the commandline was foreign to me. And quite frankly I didn't like it. Little bit later I bit the bullet and learned Grunt. And boy is it awesome. In this multi-part tutorial I hope to explain what Grunt is, why to use it, and how to install it and set it up in the most painless way possible.
What is Grunt?
At it's most basic, Grunt is a commandline tool to do automated tasks. It actually does quite more, but for the sake of this tutorial, that is what it does. You can have Grunt minify your javascript, process your LESS/SASS, concatenation, and thats just the tip if the iceberg. There is a awesome community that extends the power of Grunt every day. After a little setup, Grunt will do these tasks for you automatically. Pretty cool huh?
Why use Grunt?
Im sure you are already seeing why you should use Grunt and how it can help you. But in the event that you don't, lets go over why you would want to use Grunt in your work flow.
The way we develop webpages are changing. If you work in a large team you are likely not building simple Wordpress sites. Chances are, you are designing and developing full fledge web applications. Get that? Applications. Not webpages. So to keep up with this, we need to change the way we do our front end. We need to become more efficient and flexible. This is where Grunt helps.
Efficiency
With all the tasks that a front end developer has to do, automation will speed up the process by a large measure. The more you automate, the quicker you will be.
Consistency
Being human, we make mistakes. When making web applications, a simple error can lead to disastrous effects. Having Grunt do tasks for you will ensure that it is done the same way every time.
Flexibility
Sure, there are tools out there that will do minification, process your LESS/SASS and stuff like that. There is a good chance you are using Codekit to do these things. It's easy, and pretty slick. So why use Grunt when you are already using that. Well for starters Grunt is 100% free. But the main draw is it's community creating more and more functionality. You don't have to wait for a product release. You just download the plugin, set it up, and you are on your way.
How to install Grunt
Step 1
So let's stop talking about Grunt, and let's install it. Grunt is built using Node.js so it stands to reason that we need Node on our machine. There are many ways to do this (including the commandline) but lets take the easy road here. Go to http://nodejs.org/ and click the "install" button. This will download an installer. Simply install it using what ever way your OS does. Simple.
Step 2
Let's be honest here. Grunt is a commandline tool. You are NOT going to get out of using the commandline. But the good news is, is that all you need is some basic knowledge of the commandline. Mostly, all you need is to learn how to navigate around your file system using the cd command. But in any case, a good overview of commandline basics for MacOS can be found at http://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line. On the windows front you can use http://dosprompt.info/. But really there are tons of information out there.
When you installed Node.js it installed a package manager called NPM (Node Package Manager). It is with this, that you will be installing grunt and installing various Grunt modules (we will get into what these are later).
We have to install the Grunt CLI or rather Grunt CommandLine Interface. It allows you to run Grunt commands on the commandline.
Type this into the commandline application of your choice:
$ npm install -g grunt-cli
Step 3
We have to prepare our project a little to deal with Grunt. It involves 2 files that may seem a little confusing but we will go through it slowly.
package.json
The first of these files is our project info and dependencies file. This file is called your package.json file. You can either create it by hand, or let Node do it for you. To let Node do it for you, go to your project file in the commandline and run this command:
npm init
This will run you through some simple questions. You don't need to answer all of them. In fact, I only recommend the first 3 to start off with. If you don't want to do that, then you can use this simple template:
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
}
}
Save this as package.json. If you haven't guessed this is written in json.
Step 4
Now lets install Grunt, which is actually a module. If you are familiar with jQuery, think of modules as a plugin similar to how jQuery does it. Not exactly the same, but for all all intents and purposes, it will do.
In your commandline, travel to your project folder and in the root type:
npm install grunt --save-dev
This will install the Grunt module for the project. It will create a directory called node_modules (hint, all modules will be installed here), and with the special command "--save-dev", adds the dependency to your devDependencies in your package.json file.
Step 5
Gruntfile.js
For the last step, we need to create whats called our Gruntfile. This file basically tells grunt what to do. Create a new file and save it as Gruntfile.js (use the caps). If you are not familiar with Javascript this next part might be a little confusing, but once again we will go over it slowly. But first, here is a template to copy into your Gruntfile.js.
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Plugin configuration
});
// Load the plugin
grunt.loadNpmTasks('');
// Default task(s).
grunt.registerTask('default', ['']);
};
Let's break this 4 sections.
The "wrapper" function
Project and task configuration
Loading Grunt plugins and tasks
Custom tasks
Wrapper
The wrapper basically contains all your Grunt code. The wrapper consists of:
module.exports = function(grunt) {
// Grunt Code
};
Project and task configuration
This is a little more complex, but basically this is the settings of your plugins.
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Plugin configuration
});
Enable Grunt Plugins and Tasks
You have to tell Grunt about the plugins, this is where you do it.
// Enable the plugin
grunt.loadNpmTasks('');
Custom tasks
You can have Grunt run tasks, or task groups. Default will run by default, but you can run how ever many you want.
grunt.registerTask('default', ['']);
Doing Something
So that's a lot of set up. None of it is particularly fun. So lets actually do something fun with it. Lets use a common plugin called Uglify. This will minify your Javascript. So to use it, we need to download the module files. We do this the same way we did with the Grunt module files. With the commandline. Use:
npm install grunt-contrib-uglify --save-dev
Just like before this will download the necessary files and add the dependency code to our package.json file. We now need to register the plugin in our Gruntfile.js. Just add this to the Gruntfile.js in the place we talked about before.
grunt.loadNpmTasks('grunt-contrib-uglify');
We are now ready to configure and use the plugin. In the configuration section we specify the 'uglify' task and pass some options to it.
uglify: {
my_target: {
files: {
'output.min.js': ['input.js']
}
}
}
You first specify the output destination and then an array of the input. Technically if you only have one file to uglify, then you don't need to have it in an array. I just do it as a preference because it's easier to add to later without changing the syntax.
Next we have to add the plugin to our task. We will use the default task.
grunt.registerTask('default', ['uglify']);
That should be it for installing and configuring uglify. Our final Gruntfile.js should look like this:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Plugin configuration
uglify: {
my_target: {
files: {
'output.min.js': ['input.js']
}
}
}
});
// Load the plugin
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
Running Grunt
Now that we have anything set up to run uglification on our Javascript we need to run Grunt. This is very easy to do. In the commandline just type:
grunt
It will run through the "default" task list, in this case only being uglify, will process the files. It will notify you of any successes or errors.
Had this been on a task list different than "default", say "development"; we would run the following command:
grunt development
Finishing up
This should be a good start on getting you on your way to using Grunt in your projects. There are hundreds of plugins out there. Visit http://gruntjs.com/plugins for a good list of them. In a project I typically use the jshint, uglify, watch, and less plugins. Have a search through and see what you can do with it.
That concludes part 1 of our Grunt.js tutorial. In part 2 we will be getting deeper into some plugins and using some advanced features of Grunt. Let me know if you have any questions about Grunt in the comment section below.