Grunt Beginner's Revised Guide
- Transfer
- Tutorial
Back in March 2013, I wrote an article on the Grunt Starter Guide and it became the most visited article on my site. I wrote it at a time when I was just starting my acquaintance with Grunt , and it was more a guide for myself than for anyone else. Now, after 18 months, I felt that it was time to review how I use Grunt because now I know much more than at that time.
If you can't wait to just see the code, then all of it is on Github .
First of all, you need to make sure that you have Node and the Grunt CLI (command line interface) installed .
Our project will require several directories. Their structure is presented below:
First of all, I no longer use scaffolding tools (such as <br> grunt init or Yeoman ). I set everything up from scratch. This means that I have a lot more understanding of what is happening at the moment. It is not at all difficult once you have done it several times.
In the root of the project, create a file called Gruntfile.js
In this file, add the following code:
Believe it or not, that's all for our Gruntfile.
time-grunt tells you how much time each task and general assembly took, and jitGrunt: true tells load-grunt-config to use the faster jit-grunt task loader (this is optional, but the speed is good, right?).
Let's move on and create our base package.json file . This file will contain the dependencies of our project in the near future. Add the following (obviously, change the references to “my-project” to the real name of your project).
Now we have everything we need to start adding modules. Run each line of code in sequence below:
If you look in package.json , you should see something like this:
Here is a list of what we just installed:
grunt : the task scheduler itself.
time-grunt : an optional but nice addition - it tells you how much time each task and general assembly took.
load-grunt-config : allows us to keep our main gruntfile short and concise. More on this below.
grunt-concurrent : perform tasks simultaneously. Out of the box, Grunt performs tasks one after another, which may take some time depending on the volume and type of tasks that need to be performed. However, tasks often arise that are independent of other tasks and can be performed simultaneously.
grunt-contrib-clean : everything is very simple, this task removes garbage - use with caution!
grunt-contrib-imagemin : indispensable since all of your images need optimization.
grunt-sass: compiles your SASS / SCSS files into CSS. Please note: this module uses a faster but experimental libsass compiler. If you are experiencing problems, you should probably use the stable but slower grunt-contrib-sass .
grunt-contrib-uglify : makes your javascript beautiful and ugly.
One of the best modules I introduced is load-grunt-config . It allows us to put the config for each of our tasks in a separate file. This is much more convenient than storing all the settings in one big Gruntfile.
Create the following files in the grunt directory :
Please note: the names of these files must match the names of the tasks.
Copy and paste the config for each task below into the corresponding file.
Here we define various aliases for our tasks:
default - performs prod tasks when grunt starts at the command line.
dev - performs development tasks (but not image tasks).
img - performs image tasks.
devimg - Performs development and image tasks.
prod - performs production and image tasks.
Click here for more information on setting up aliases for tasks using load-grunt-config .
For example, take development tasks. You can see that they are configured to run clean first and then sass: dev and uglify at the same time to restore css and javascript.
Click here for more information on configuring grunt-concurrent .
Setting up grunt-contrib-clean is pretty simple. Here I just deleted the entire contents of the / dist directory . use this task with caution - it will delete indiscriminately everything you say without any warning. So make sure you configure it correctly.
Click here for more information on configuring grunt-contrib-clean .
The config above simply optimizes all images in src / images / and saves them in dist / images / .
Click here for more information on configuring grunt-contrib-imagemin .
I divided sass tasks into development and production processes. The config is very similar, but for development purposes, I set the output style to " nested " and included a code map.
Click here for more information on configuring grunt-sass .
JShint checks your jsvascript and ensures that everything is type-top with it.
Click here for more information on configuring grunt-contrib-jshint .
Uglify simply takes your Javascript files and minifies them.
Click here for more information on configuring grunt-contrib-uglify .
Watch launches these tasks whenever files that it monitors in any way change - they are added, deleted, edited.
Note: The easiest way to get Livereload working is to install the browser extension .
Click here for more information on configuring grunt-contrib-watch and Livereload.
If you have finished setting up your project as described above, now you can start the tasks. As discussed earlier, there are various task aliases that you can run. Now just type grunt at the command line at the root of your project.
If everything goes well you will see the boot text scrolling down the screen, and then a message similar to this:

I love the little summaries that grunt-time provides . I see how much time it took to complete each of the sets of tasks. Plus how much time the whole assembly process took.
Depending on your needs, you could also run grunt dev , grunt devimg , or grunt img .
You can also run grunt watch if you want grunt to monitor changes to your .sass and .js and automatically run sass or jshint and uglify.
This is actually all. If you experiment with what is presented above, you will soon gain confidence, begin to add tasks and modify the workflow for the better in accordance with your requirements.
Once again, the code attached to this article can be found on Github .
If you can't wait to just see the code, then all of it is on Github .
Install Node and Grunt for all users
First of all, you need to make sure that you have Node and the Grunt CLI (command line interface) installed .
- Node.js has installers for various operating systems. All information can be found here .
- After installing Node.js, just run the following command in your terminal (I use iTerm2 ) to install grunt-cli
npm install -g grunt-cli
Creating a project directory
Our project will require several directories. Their structure is presented below:
grunt/
src/
src/images/
src/scripts/
src/styles/
Create gruntfile
First of all, I no longer use scaffolding tools (such as <br> grunt init or Yeoman ). I set everything up from scratch. This means that I have a lot more understanding of what is happening at the moment. It is not at all difficult once you have done it several times.
In the root of the project, create a file called Gruntfile.js
In this file, add the following code:
module.exports = function(grunt) {
require('time-grunt')(grunt);
require('load-grunt-config')(grunt, {
jitGrunt: true
});
};
Believe it or not, that's all for our Gruntfile.
time-grunt tells you how much time each task and general assembly took, and jitGrunt: true tells load-grunt-config to use the faster jit-grunt task loader (this is optional, but the speed is good, right?).
Create Package File
Let's move on and create our base package.json file . This file will contain the dependencies of our project in the near future. Add the following (obviously, change the references to “my-project” to the real name of your project).
{
"name": "my-project",
"version": "0.0.1",
"description": "My project"
}
Add Dependencies
Now we have everything we need to start adding modules. Run each line of code in sequence below:
npm install grunt --save-dev
npm install time-grunt --save
npm install load-grunt-config --save-dev
npm install grunt-concurrent --save-dev
npm install grunt-contrib-clean --save-dev
npm install grunt-contrib-imagemin --save-dev
npm install grunt-sass --save-dev
npm install grunt-contrib-uglify --save-dev
If you look in package.json , you should see something like this:
{
"name": "my-project",
"version": "0.0.1",
"description": "My project",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-concurrent": "^1.0.0",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-imagemin": "^0.8.1",
"grunt-contrib-uglify": "^0.6.0",
"grunt-sass": "^0.16.1",
"load-grunt-config": "^0.13.1"
},
"dependencies": {
"time-grunt": "^1.0.0"
}
}
Here is a list of what we just installed:
grunt : the task scheduler itself.
time-grunt : an optional but nice addition - it tells you how much time each task and general assembly took.
load-grunt-config : allows us to keep our main gruntfile short and concise. More on this below.
grunt-concurrent : perform tasks simultaneously. Out of the box, Grunt performs tasks one after another, which may take some time depending on the volume and type of tasks that need to be performed. However, tasks often arise that are independent of other tasks and can be performed simultaneously.
grunt-contrib-clean : everything is very simple, this task removes garbage - use with caution!
grunt-contrib-imagemin : indispensable since all of your images need optimization.
grunt-sass: compiles your SASS / SCSS files into CSS. Please note: this module uses a faster but experimental libsass compiler. If you are experiencing problems, you should probably use the stable but slower grunt-contrib-sass .
grunt-contrib-uglify : makes your javascript beautiful and ugly.
Task setting
One of the best modules I introduced is load-grunt-config . It allows us to put the config for each of our tasks in a separate file. This is much more convenient than storing all the settings in one big Gruntfile.
Create the following files in the grunt directory :
grunt/aliases.yaml
grunt/concurrent.js
grunt/clean.js
grunt/imagemin.js
grunt/jshint.js
grunt/sass.js
grunt/uglify.js
grunt/watch.js
Please note: the names of these files must match the names of the tasks.
Copy and paste the config for each task below into the corresponding file.
ALIASES.YAML
default:
description: 'Default (production) build'
tasks:
- prod
dev:
description: 'Development build'
tasks:
- 'concurrent:devFirst'
- 'concurrent:devSecond'
img:
description: 'Image tasks'
tasks:
- 'concurrent:imgFirst'
devimg:
description: 'Development build and image tasks'
tasks:
- dev
- img
prod:
description: 'Production build'
tasks:
- 'concurrent:prodFirst'
- 'concurrent:prodSecond'
- img
Here we define various aliases for our tasks:
default - performs prod tasks when grunt starts at the command line.
dev - performs development tasks (but not image tasks).
img - performs image tasks.
devimg - Performs development and image tasks.
prod - performs production and image tasks.
Click here for more information on setting up aliases for tasks using load-grunt-config .
CONCURRENT.JS
module.exports = {
// Опции
options: {
limit: 3
},
// Задачи разработки
devFirst: [
'clean',
'jshint'
],
devSecond: [
'sass:dev',
'uglify'
],
// Производственные задачи
prodFirst: [
'clean',
'jshint'
],
prodSecond: [
'sass:prod',
'uglify'
],
// Задачи изображений
imgFirst: [
'imagemin'
]
};
For example, take development tasks. You can see that they are configured to run clean first and then sass: dev and uglify at the same time to restore css and javascript.
Click here for more information on configuring grunt-concurrent .
CLEAN.JS
module.exports = {
all: [
"dist/"
]
};
Setting up grunt-contrib-clean is pretty simple. Here I just deleted the entire contents of the / dist directory . use this task with caution - it will delete indiscriminately everything you say without any warning. So make sure you configure it correctly.
Click here for more information on configuring grunt-contrib-clean .
IMAGEMIN.JS
module.exports = {
all: {
files: [{
expand: true,
cwd: 'src/',
src: ['images/*.{png,jpg,gif}'],
dest: 'dist/'
}]
}
};
The config above simply optimizes all images in src / images / and saves them in dist / images / .
Click here for more information on configuring grunt-contrib-imagemin .
SASS.JS
module.exports = {
// Development settings
dev: {
options: {
outputStyle: 'nested',
sourceMap: true
},
files: [{
expand: true,
cwd: 'src/styles',
src: ['*.scss'],
dest: 'dist/styles',
ext: '.css'
}]
},
// Production settings
prod: {
options: {
outputStyle: 'compressed',
sourceMap: false
},
files: [{
expand: true,
cwd: 'src/styles',
src: ['*.scss'],
dest: 'dist/styles',
ext: '.css'
}]
}
};
I divided sass tasks into development and production processes. The config is very similar, but for development purposes, I set the output style to " nested " and included a code map.
Click here for more information on configuring grunt-sass .
JSHINT.JS
module.exports = {
options: {
reporter: require('jshint-stylish')
},
main: [
'src/scripts/*.js'
]
};
JShint checks your jsvascript and ensures that everything is type-top with it.
Click here for more information on configuring grunt-contrib-jshint .
UGLIFY.JS
module.exports = {
all: {
files: [{
expand: true,
cwd: 'src/scripts',
src: '**/*.js',
dest: 'dist/scripts',
ext: '.min.js'
}]
}
};
Uglify simply takes your Javascript files and minifies them.
Click here for more information on configuring grunt-contrib-uglify .
WATCH.JS
module.exports = {
options: {
spawn: false,
livereload: true
},
scripts: {
files: [
'src/scripts/*.js'
],
tasks: [
'jshint',
'uglify'
]
},
styles: {
files: [
'src/styles/*.scss'
],
tasks: [
'sass:dev'
]
},
};
Watch launches these tasks whenever files that it monitors in any way change - they are added, deleted, edited.
Note: The easiest way to get Livereload working is to install the browser extension .
Click here for more information on configuring grunt-contrib-watch and Livereload.
Task launch
If you have finished setting up your project as described above, now you can start the tasks. As discussed earlier, there are various task aliases that you can run. Now just type grunt at the command line at the root of your project.
If everything goes well you will see the boot text scrolling down the screen, and then a message similar to this:

I love the little summaries that grunt-time provides . I see how much time it took to complete each of the sets of tasks. Plus how much time the whole assembly process took.
Depending on your needs, you could also run grunt dev , grunt devimg , or grunt img .
You can also run grunt watch if you want grunt to monitor changes to your .sass and .js and automatically run sass or jshint and uglify.
Summary
This is actually all. If you experiment with what is presented above, you will soon gain confidence, begin to add tasks and modify the workflow for the better in accordance with your requirements.
Once again, the code attached to this article can be found on Github .