There are plenty of build tools options in the current market – from Maven and Ant to Java, Gradle or the classic Make. But Grunt is different. It was done in JavaScript and focused on automating front-end tasks.
If you, for example, want to follow good performance practices for websites, you should worry about minifying CSS and JavaScript or even adding files to reduce the number of requests and even make CSS sprites. Or maybe you’re using some CSS pre-processor such as LESS, SASS or Stylus.
The point is: you will need to run a minifier, a file concatenator, a preprocessor, and probably many other small tools. Turning all this individually is insane and we want to automate the whole process. This is where Grunt.js comes in.
Grunt.js
It is a build task automation tool made entirely in JavaScript. It runs on Node.js, which is a JavaScript interpreter that you can install on your computer. At the end of the article we’ll see the installation process for when to run the first time.
The main point about Grunt is a file that describes the tasks to be performed in the project build. And that same file is written in JavaScript, then no need of XML or strange syntaxes, like in other tools. This file is the Gruntfile.js that you create at the root of your project.
Its basic structure is something like this:
module.exports = function(grunt) {
grunt.initConfig({
// tasks configs
});
// load the plugins
grunt.loadNpmTasks('name-of-the-plugin');
};
Notice that it is a JS function that calls other configurations. The initConfig
is where we will put the rules of the tasks that we want to execute (where we indicate, for example, which files to minify). Note that it receives a JS object, as in a JSON. In the end, we call loadNpmTasks
to register a Grunt plugin that will bring some functionality.
Minimizing JS with Uglify
Let’s set up JavaScript minification using UglifyJS. We registered the plugin, called grunt-contrib-uglify
using grunt.loadNpmTasks('grunt-contrib-uglify');.
The configuration itself is very simple, just list the files to be mined (source and destination):
module.exports = function(grunt) {
grunt.initConfig({
uglify: {
'build/home.js': 'src/home.js',
'build/main.js': 'src/main.js'
}
});
// load the plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
};
In the example, I assumed you create your files in a src/folder
and want to run the final versions in a build/folder
(of course you can use other names). You could also minify the file itself without copying it to a different folder, but you will hardly want to minify your own source file.
Finally, to execute this task, simply run grunt uglify
on the terminal.
CSS Preprocessing
Now it is very easy to add other plugins and perform other tasks. For example, using grunt-contrib-less
, we can compile a LESS file for CSS:
less: {
'build/style.css': 'src/style.less'
}
To execute it, just run grunt less
on the terminal. To compile SASS or Stylus, it’s pretty much the same thing, just change the plugin name.
If you want to concatenate the CSS files in one, besides compiling all the LESS, you can do this by listing the files:
less: {
'build/style.css': ['src/header.less', 'src/main.less', 'src/footer.less']
}
And that goes for other tasks as well, such as the uglify we saw earlier. And we’re just seeing the beginning of Grunt. You can do a lot more in these settings, to make things even easier.
In fact, one feature we can do is simplify the execution of tasks, so we do not have to call one by one when running the command. We can set new tasks with grunt.registerTask()
. We just need to pass the name of the new task and a list of tasks to be executed:
grunt.registerTask('default', ['uglify', 'less']);
The new default task can be run on the command line with grunt default
and will run both less and uglify for us. Better yet, this default name is special, so we can execute everything just by running grunt
on the terminal.
More Tasks
There are many other useful plugins in Grunt. For CSS compilers, we have the LESS, Stylus and SASS. For JS, we also have CoffeeScript. To minify, we have uglify, cssmin and htmlmin. We also have basic tasks such as copying (copy
), simple concatenation (concat
) and clean. And still watch with livereload
for your browser to automatically update when a file is changed.
These are just some of the official plugins. There is a huge list of community plugins to do the most varied tasks,such as the powerful grunticon
that generates a sprite of SVG files with fallback for PNGs.
The Installation of Grunt.js
Grunt is based on Node.js, so you must first install it. On the site there is already a download button, or you can use the package installer of your operating system (apt-get
on Linux, homebrew
on Mac, etc.)
After you’ve installed Node, you can install the Grunt command-line tools by just running on the terminal:
npm install -g grunt-cli
Next step is to configure our project as a node artifact, so we can install the plugins and other dependencies. Create a package.json
file at the root of your project where we will place project settings – the minimum is the project name and a version number:
{
"name": "grunt-demo",
"version": "0.0.1"
}
Now the Grunt installation is done according to the project running:
npm install grunt -- save-dev
Each grunt plugin you will use will install the same way:
npm install grunt-contrib-uglify -- save-dev
npm install grunt-contrib-less -- save-dev
Then just use these plugins in your Gruntfile.js as we saw before.
Conclusion
We have now gone through a brief introduction to grunt, its ideas and a few resources. The official Grunt website has much more documentation.
Grunt is a powerful tool to automate build tasks and is primarily focused on the front end, but it can be used for all types of builds. It can even be used to build the front-end part of a larger project with Java in the back-end, for example.