5 Grunt Tasks You Won’t Want to Miss!
Unless you’ve lived under a stone for the past few months, you’ve surely heard about Grunt or one of the other task runners released like Gulp.js (more on this topic in our article An Introduction to Gulp.js). This family of tools has taken the frontend landscape by storm, revolutioning the way thousands of developers deal with tedious activities like concatenation, minification, image optimization, and so on.
If you’re new to the world of task runners, and particularly to Grunt, you can either refer to the article Automate Recurring Tasks with Grunt or the Grunt getting started guide.
In this article I’ll show you five Grunt tasks (sometimes referred as Grunt plugins) that you won’t want to miss!
grunt-autoprefixer
If you’ve recently spent some time writing CSS, you know that we have to deal with a lot of experimental properties and vendor prefixes. This activity is so painful that it has contributed to the success of websites such as Can I Use and CSS3 Please. Thanks to grunt-autoprefixer, this activity won’t be such a pain anymore.
grunt-autoprefixer is a task based on the Autoprefixer library that parses CSS and adds vendor-prefixed CSS properties. The data that determines if a property needs one or more prefixes are extracted from the Can I Use database. In grunt-autoprefixer we can specify several options, but the most important one is surely browsers
. The latter accepts an array of values that allows us to specify which browsers and versions we’re targeting in our project. The aim is to add only the prefixes we really need so our CSS will be as lightweight as possible.
A basic configuration example for this task is shown below. In this configuration, we’ve specified a file to parse named main.css
. The output is written to a file named `main-prefixed.css`. Additionally, the output will contain the prefixes for the last two versions of each browser supported, plus Internet Explorer 8, Internet Explorer 9, and Opera 12.1 (the last version to use the Presto engine).
grunt.initConfig({
autoprefixer: {
options: {
browsers: ['last 2 version', 'ie 8', 'ie 9', 'Opera 12.1']
},
dist: {
src: 'src/css/main.css',
dest: 'dest/css/main-prefixed.css'
}
}
});
grunt-uncss
While we’re talking about CSS, let’s take a look at grunt-uncss. This task, based on UnCSS, developed by the awesome Addy Osmani removes unused CSS from a project. This task is particularly useful when using a CSS framework in a project, as it’s highly unlikely that we’re using all of the framework’s components. Using grunt-uncss allows us to reduce the size of the final CSS file, and thus improve download times.
Unfortunately, the UnCSS module has two important limitations that are reflected in grunt-uncss. The first one is that UnCSS isn’t able to recognize CSS classes added at runtime by JavaScript or by user interaction (via hover, click, and so on). We can partially solve this issue by specifying the classes we don’t want to remove in an option called ignore
that accepts both literal names and regex patterns. The second issue is that the parser isn’t able to work with complex selectors. When this happens an error is raised. The best way to fix it is to move the problematic selector to a separate style sheet that the parser will not process.
The following image is taken from the official repository, and shows the task in action.
grunt-wiredep (formerly known as grunt-bower-install)
Grunt’s fame has grown with the help of Bower and yo (which form the Yeoman workflow). Bower is a dependency manager for JavaScript and CSS. If you’ve ever used it, you’ll know that once downloaded we have to manually add the components of the project inside our main HTML file. This may be a tedious activity to perform if we have more than a couple dependencies. Fortunately for us, there is a Grunt task, called grunt-wiredep (formerly known as grunt-bower-install), that we can employ. grunt-wiredep finds the components of our projects and injects them into our source code based on our settings.
A basic configuration of this task is as follows:
grunt.initConfig({
wiredep: {
app: {
src: [
'index.html'
]
}
}
});
With this configuration in place, to manage the JavaScript dependencies of our project, we have to place this code in our main HTML file (index.html
following the code above):
<!-- bower:js -->
<!-- endbower -->
Now every time we want to inject or update the dependencies, we can simply run the command grunt-widep
. The result of this command will generate a result like the following:
<!-- bower:js -->
<script src="bower_components/jquery/jquery.js"></script>
<!-- endbower -->
grunt-modernizr
When talking about grunt-autoprefixer we mentioned the concept of experimental features in CSS. When we want to use modern JavaScript capabilities, we need to test the browser to check if it supports a given feature. To achieve this task (but also to test for CSS experimental properties), the best library we can use is Modernizr. grunt-modernizr is a task based on Modernizr that parses the files of our project searching for references to Modernizr. Then, it outputs a minified version of the library that includes only the features in use. This process allows us to further reduce the weight of our project.
grunt-modernizr is heavily customizable through the many options it provides. The following is a very basic example of configuration:
grunt.initConfig({
modernizr: {
dist: {
devFile: 'path/to/modernizr.js',
outputFile: 'path/to/distribution-folder/custom-modernizr.js',
files: {
src: [
'path/to/scripts/**/*.js',
'path/to/styles/**/*.css',
]
}
}
}
});
This configuration sets the path to the Modernizr source file and where the custom build will be created. Additionally, it specifies the files to scan for references to Modernizr. In our case the files are all of the .js
and .css
files inside the path/to/scripts
and path/to/styles
folders, respectively.
grunt-concurrent
If you’re using a computer with a powerful processor(s), running the tasks of your Gruntfile.js
may take just few seconds. But, what if the process takes over a minute? How we can speed up the process? grunt-concurrent to the rescue! grunt-concurrent allows you to run grunt tasks concurrently, improving build time significantly. An example configuration is shown below.
grunt.initConfig({
concurrent: {
test: [
'copy',
'autoprefixer'
],
build: [
'concat',
'uncss'
]
}
});
In this example we run the copy and the autoprefixer tasks concurrently when executing the test
task, and run the concat and the uncss tasks concurrently when executing the build
task.
Conclusion
In this article I introduced you to some of the most interesting tasks for Grunt, at least in my opinion. These tasks are a bit above the level of the very basic tasks that we typically employ in our projects like grunt-contrib-clean, grunt-contrib-copy, and grunt-contrib-concat. This is definitely not a comprehensive list of interesting tasks, as there are a lot of other useful ones out there.
Now it’s your turn. What do you think about the tasks presented? Did you know about them? Are there any tasks you love and want to share? Let’s start a discussion.