Getting Started With Grunt
This tutorial will help you get started with Grunt, a useful Javascript task runner with automation capabilities.
We’re hearing a lot about GruntJS these days and you may wondering why. I’ve been using it for a couple of months and it helped me a great deal on many aspects of my developments. By reading this article, you’ll understand why Grunt should be part of your development process.
Why Grunt?
My development process already works, so why bother?
Let’s take an example. Inside your project, you probably have a bunch of files in their development format:
- css files
- js files
- Images
When production time comes, you have to run it through your favorite concatenators, minifiers, optimizers, etc. And everything is working like a charm. But every time you have to make a change to your project, you have to run everything again and it’s beginning to become a hassle. This is where Grunt, the automated task runner, comes to your rescue!
The power of Grunt
Grunt will watch for changes in your project and automatically run the processes of your choice (sass or less processing, image optimization, code linting, page refresh etc…). And once production time comes, a simple command will also run all the specific commands you defined (concatenation, minification, unit tests, etc…). Once it is configured, you’ll never have to think about all that ever again! Isn’t it great?
All the tools you’re already using in your process are available as Grunt plugins. Compass, Sass, Less, JSLint, Optipng, uglify and many more. No more hassle, no more pain, Grunt lets you focus on the important part: your code. But like every new technology, there is a little downside: you have to learn how to use it. And that’s exactly what you will learn with this tutorial.
Prerequisites
Install Node.js
Grunt and Grunt plugins are installed and managed via npm, the Node.js package manager.
So the first thing you need to do is install Node.js.
Install Grunt CLI
To be able to use Grunt, you’ll need to install the command line interface:
npm install –g grunt-cli
The -g
means that the program will be installed globally on your machine and not specifically for this project.
Setting up a new Grunt project
To be able to run Grunt, you will need to have 2 files in your project directory:
- A
gruntfile.js
file, which is the Grunt configuration file. - A
package.json
file (used by npm) in which you’ll list Grunt and the Grunt plugins your project needs.
Package.json
The file in its bare bones state should look like this:
{
"name": "introduction-to-grunt",
"version": "0.1.0"
}
Now, let’s install grunt in our project directory. To install Grunt and its plugins, the easiest way is to run the command npm install <module> --save-dev
. The npm module will be then saved locally. --save-dev
tells npm to also update the package.json file, adding the module to the “devDependencies” section. Ok, let’s do this! Run this command:
npm install grunt --save-dev
Your package.json
should look like this now:
{
"name": "introduction-to-grunt",
"version": "0.1.0",
"devDependencies": {
"grunt": "^0.4.5"
}
}
Check your project directory, a folder named node_modules
should have been created. It contains the Grunt module. Well, that was easy! But what about my teammates?
Anyone working on your project will be able to install all the node modules you specified in the package.json
file by running npm install
at the root folder. So no need to put the node_modules
directory in your version control.
Gruntfile.js
Now let’s move on to the core configuration. The file in its bare bones state will look like this:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json')
});
};
The “wrapper” function is the module.exports
function in which we initialize Grunt and telling it to read our package.json
file. Ok, basically, this does nothing; so let’s add a plugin to make it useful.
How to use a plugin
Let’s assume we are developping an awesome javascript application. When the app is finished, we want our code to be minified in production to make it faster to download. What we need is a minifier. If you take a look at the official Grunt plugins directory and search for “minify”, you’ll find the uglify plugin.
Adding the plugin
Let’s follow the plugin documentation and install it:
npm install grunt-contrib-uglify --save-dev
As usual, the package file and module directory will be updated.
Now let’s enable the plugin inside our gruntfile:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json')
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
};
Our module is now ready to be used!
Configuring the plugin
Let’s say that our javascript is written in index.js
inside the “js” folder. We want to uglify that file and save the ugilfied version as index.min.js
.
We just need to add this to the initConfig function in our gruntfile:
uglify: {
build: {
src: 'js/index.js',
dest: 'js/index.min.js'
}
}
Now if we run the uglify command with grunt uglify
it will already work like a charm.
The thing is, you’ll have way more than one task to run everytime you want to put your project in production. So let’s make a default task that will call all the tasks you need by using the registerTask
command:
// Default tasks.
grunt.registerTask('default', ['uglify']);
To be sure we’re on the same page here, here what’s your gruntfile should look like:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: 'js/index.js',
dest: 'js/index.min.js'
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default tasks.
grunt.registerTask('default', ['uglify']);
};
Now let’s run the grunt
command. You’ll see an output looking like that:
Running "uglify:build" (uglify) task
>> 1 file created.
Done, without errors.
If you check your js folder, you’ll see an index.min.js
file containing all your index.js code minified and ready to be deployed on production. Awesome! But for now we still have to run grunt
manually each time we want to perform our tasks. And that’s when we need the most magical part of Grunt: automation!
Automating tasks
Now we would like Grunt to « watch » for changes to our files and run automatically when such change is detected. This is done by using the « watch » plugin. Let’s go to the plugin page and install it accordingly to the documentation.
npm install grunt-contrib-watch --save-dev
Let’s update our gruntfile to load the npm task:
grunt.loadNpmTasks('grunt-contrib-watch');
Now let’s set up our « watch » task so that it runs our uglify task whenever index.js
file is modified. Just like before, we just need to follow the plugin documentation to do so. Here is the complete gruntfile updated:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: 'js/index.js',
dest: 'js/index.min.js'
}
},
watch: {
scripts: {
files: ['js/index.js'],
tasks: ['uglify']
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default tasks.
grunt.registerTask('default', ['uglify']);
};
Now, when we run the grunt watch
command, we can just forget about it. Run the command and change your index.js
file. Now save it and check out the command line, you should notice something like this:
>> File "js/index.js" changed.
Running "uglify:build" (uglify) task
>> 1 file created.
It shoud have succesfully created the minified version of index.js
. That’s all there is to it! Everything is done automatically without having to run any command each time you change your code. Automation at its finest!
Conclusion
Now you should have a better view of what Grunt can do for you. All your development and production tasks automatically running without worrying about it. In my next tutorial, I will write a fully functional grunt configuration to help you really use it in your everyday development. I will be running Sass and Compass processing, image optimization, linting and many more.
You can download the full working project made with this article on Github: https://github.com/mvidailhet/getting-started-with-grunt
I hope you enjoyed this tutorial and found it useful. I’d love to hear about your thought about it in the comment section. Thanks for reading! And may code be with you!