Grunt in Action

Exclusive offer: get 50% off this eBook here
Getting Started with Grunt: The JavaScript Task Runner

Getting Started with Grunt: The JavaScript Task Runner — Save 50%

A hands-on approach to mastering the fundamentals of Grunt with this book and ebook

$20.99    $10.50
by Jaime Pillora | January 2014 | Open Source Web Development

In this article by Jaime Pillora, author of Getting Started with Grunt: The JavaScript Task Runner, we will perform additional transformations on set of source files by using Grunt.

(For more resources related to this topic, see here.)

Step 4 – optimizing our build files

At this point, we should have a structured set of source files and can now perform additional transformations on the result. Let's start by downloading the plugins from npm and saving them in our package.json file:

$ npm install --save-dev grunt-contrib-uglify grunt-contrib-cssmin
grunt-contrib-htmlmin

Then, at the top of our Gruntfile.js file, where we have loaded our other Grunt plugins, we will load our new additions with:

grunt.loadNpmTasks("grunt-contrib-uglify"); grunt.loadNpmTasks("grunt-contrib-cssmin"); grunt.loadNpmTasks("grunt-contrib-htmlmin");

Scripts

We will start by compressing our scripts. In this example, we use the grunt-contrib-uglify plugin http://gswg.io#grunt-contrib-uglify), which is a wrapper around the popular UglifyJS library (http://gswg.io#uglifyjs). Now we have loaded the plugin, which provides the uglify task, we just need to configure it:

uglify: { compress: { src: "<%= coffee.build.dest %>", dest: "<%= coffee.build.dest %>" } }

Here, inside the uglify property, we have made a compress target, which has src and dest set to the same file. Instead of entering the actual filename, we are making use of Grunt templates to retrieve the value at the given configuration path (coffee.build.dest), which in this case, resolves to build/js/app.js. Grunt templates make it easy to have a single source of truth within our configuration. Therefore, if we ever want to change the file path of our JavaScript, we only need to change one configuration entry.

Since we have set the source and destination to the same file path, in effect, we are overwriting our JavaScript with the compressed version of itself. However, if we were writing a JavaScript library instead of a web application, we'd most likely want to compress our app.js file into an app.min.js file, so its users could download an uncompressed and a compressed version.

Running this uglify task with this basic configuration should result in the following app.js file:

(function(){var a,b;a=function(a,b){return a+b},b=function(a,b)
{return a-b},alert(a(7,b(4,1)))}).call(this);

Generally, this will suffice, however, UglifyJS also offers advanced features. For example, in some cases, we might have portions of code that are only used during development. We could remove this unnecessary code with the following technique. By defining a DEBUG variable and place our debug-related code inside an if block as follows:

if(DEBUG) { //do things here }

Then, if we used the following options object inside our uglify configuration as follows:

options: { compress: { global_defs: { "DEBUG": false }, dead_code: true } }

This would result in UglifyJS locking the value of DEBUG to false and also to remove the inaccessible code (dead code). Therefore, in addition to compressing code, we also have the ability to completely remove code from our builds. The documentation for this feature can be found at http://gswg.io#grunt-contrib-uglify-conditional-compilation.

Styles

To compress our styles, we use the grunt-contrib-cssmin plugin (http://gswg.io#grunt-contrib-cssmin), which is a wrapper around the clean-css library (http://gswg.io#clean-css). Since we have installed this plugin, we just need to include the cssmin task configuration:

cssmin: { compress: { src: "<%= stylus.build.dest %>", dest: "<%= stylus.build.dest %>" } }

Similar to our scripts configuration, we can see that the only real difference is that we point to the stylus task's output instead of pointing to the coffee task's output. When we run grunt cssmin, our css/app.css file should be modified to the following one:

html,body{margin:0;padding:0}.content .middle{font-size:16pt}@media
(max-width:768px){.content .middle{font-size:8pt}}

Views

Finally, to compress our views, we will use the grunt-contrib-htmlmin plugin (http://gswg.io#grunt-contrib-htmlmin), which is a wrapper around the html-minifier library (http://gswg.io#html-minifier). The htmlmin configuration has a little more to it: since its compression options are disabled by default, we need to enable the rules we wish to use:

htmlmin: { options: { removeComments: true, collapseWhitespace: true, collapseBooleanAttributes: true, removeAttributeQuotes: true, removeRedundantAttributes: true, removeOptionalTags: true }, compress: { src: "<%= jade.build.dest %>", dest: "<%= jade.build.dest %>" } }

Now our htmlmin task is configured, we can run it with grunt htmlmin, which should modify our build/app.html to the following:

<!DOCTYPE html><html><head><link rel=stylesheet href=css/app. css><body><section class=header>this is the <b>amazing</b> header section</section><section class=content><div class=top>some content with this on top</div><div class=middle>and this in the middle</ div><div class=bottom>and this on the bottom</div></section><section class=footer>and this is the footer, with an awesome copyright symbol with the year next to it - © 2013</section><script src = js/app. js></script>

In addition to the GitHub repository, we can read more about html-minifier on Juriy "Kangax" Zaytsev's blog at http://gswg.io#experimenting-with-html-minifier.

Summary

In this article we performed additional transformations on set of source files by using Grunt.

Resources for Article:


Further resources on this subject:


Getting Started with Grunt: The JavaScript Task Runner A hands-on approach to mastering the fundamentals of Grunt with this book and ebook
Published: February 2014
eBook Price: $20.99
Book Price: $34.99
See more
Select your format and quantity:

About the Author :


Jaime Pillora

Jaime Pillora  is a passionate full-stack JavaScript developer, an open source advocate and contributor, and is currently the CTO of Luma Networks, a well-funded networking startup in Sydney, Australia.

Jaime has always been interested in all things computer science, and from a young age, he began to devote his time and effort to learning and perfecting his knowledge in the field. Jaime holds a Bachelor of Computer Science from the University of New South Wales. In all of his work, Jaime strives to reduce technical debt while maintaining maximum efficiency; this is done through software engineering best practices, combined with using the best tools for the given situation. Grunt is one such tool, which is utilized in every frontend project. Jaime's interest in Grunt began early on in his development career and he has since become a renowned expert.

Jaime has been working as a frontend JavaScript developer since 2008, and a backend JavaScript developer utilizing Node.js since 2011. Currently, Jaime leads all software development at Luma Networks, who is implementing software-defined networking on commodity hardware utilizing JavaScript.

Books From Packt


Jasmine JavaScript Testing
Jasmine JavaScript Testing

 JavaScript Testing Beginner's Guide
JavaScript Testing Beginner's Guide

JavaScript Unit Testing
JavaScript Unit Testing

Object-Oriented JavaScript
Object-Oriented JavaScript

 Moodle JavaScript Cookbook
Moodle JavaScript Cookbook

 Object-Oriented JavaScript - Second Edition
Object-Oriented JavaScript - Second Edition

Instant Testing with QUnit [Instant]
Instant Testing with QUnit [Instant]

 Google Maps JavaScript API Cookbook
Google Maps JavaScript API Cookbook


Your rating: None Average: 1.3 (4 votes)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
d
5
Y
h
2
N
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software