November 10, 2011

Combine, Minify and Copy your JS's to your .war file using Gradle

So - In the course of work I was introduced to Gradle.
WTF is Gradle, one might ask - in brief? It's a much flexible manner of building your projects than Ant or Maven. It's based on Groovy (which always makes me laugh thinking on the nerd who came up with that name and thought he is so damn cool), and I leave it to you to go and read about it.

First thing first I wanted to build my .war file. No problem there. Just apply the "war" plugin to your gradle.build file and you're done. Seriously - that's it.

apply plugin: 'war'

So I have my .war file empty and now I want to add my JavaScript to it. Oh, wait - I want to add my minified JavaScript to it, not just that, but I want to combine all of my JS files into one, and just then minify it. To the rescue comes gradle-js-plugin which can minify my files using the infamous Google's Closure Compiler and of course the easy way gradle lets you arrange and configure it's tasks.

So I added this plugin, like this

apply plugin: 'js'

And asked it nicely to combine all the files and simple-optimize it. As you can see, my JS files are under the src/main/javascript directory

combineJs {
input = fileTree(dir: "${projectDir}/src/main/javascript", include: "**/*.js")
output = file("${buildDir}/all.js")
}

minifyJs {
input = file("${buildDir}/all.js")
output = file("${buildDir}/all-min.js")
compilationLevel 'SIMPLE_OPTIMIZATIONS'
warningLevel = 'QUIET'
}

As you remember I wanted to make all that before I copy it into my war so, I've added this procedure before the .war building. Again - compared to Maven, it's done pretty easily by using the doFirst task method

war.doFirst {
tasks.combineJs.execute()
tasks.minifyJs.execute()
}

Ok - so now we have a combined minified JS file on our build directory, the next thing to do is to copy it into the .war file. Here I use the war plugin again and use it's webInf() method to add some content to the WEB-INF. I'm copying the minidified file into the root of the webapp under a directory named "js".
Actually the webInf(method) is responsible for adding resources to the WEB-INF directory, not the root of the webapp, but by adding "/" before the "js" I've worked around it.

war.webInf {
from "${buildDir}/all-min.js"
into "/js/"
}

There you have it. Running gradle build will create our webapp with all the above included.
I guess that this is not the last post on the topic, since gradle will probably walk with me several miles, so stay tuned.

Cheers.

2 comments:

Amin Zamani said...

Hallo,
can someone tell me how to use this plugin to minify every javascript file inside his own javascript file?

Example:
a.js will be minified to b-min.js
b.js will be minidified to b-min.js

Thanks for a reply!

ADI said...

Here is a blog post, explaining how to create minification script for JS and CSS in gradle. This even makes the thing faster by using parallel threads. check it out! :-

Minify JS and CSS in Gradle