Automate Compressing JS and CSS with ANT

Posted: 31st December 2009 by Adam Presley in Development
Tags: , ,

I’m still a bit of a n00b with ANT still, but I took the time today to improve my skills with it a tad to help automate a task which has become quite repetitive. Once we are ready to roll changes to our application we first have to minify our JavaScript and CSS files. We use the YUI Compressor which is a very nice compression engine for both JS and CSS. It also just so happens that they have a Java executable JAR to run compression against your files with.

As such I set out to make an ANT script. For an entry talking about the basics of building ANT scripts see my blog entry on Using ANT to Automate a Build. In this post I’m simply going to cover how to call the JAR file to perform minification.

First and foremost download the YUI Compressor Java tool, and extract it to some accessible location. This is the application that does all the magic.

To make life easier I started with a few properties to make this a tad more configurable. Below I setup properties for the client’s application directory, the path to the compressor JAR, as well as the JavaScript and CSS directories.

1
2
3
4
	<property name="app" value="app-folder" />
	<property name="compressorJar" value="\\devpath\yui-compressor\build\yuicompressor-2.4.2.jar" />
	<property name="jsSourceDir" value="\\devpath\${app}\js" />
	<property name="cssSourceDir" value="\\devpath\${app}\css" />

After this we create a target… we’ll call it minify ( that’s original… :/ ). In this method we want to do two things: minify our JavaScript file, and minify our CSS file. Clearly in my case we have only two files to minify, and your mileage may vary. Let’s take a look at that.

1
2
3
4
5
6
7
8
9
10
		<java jar="${compressorJar}" fork="true" failonerror="true">
			<arg value="--line-break" />
			<arg value="4000" />
			<arg value="--type" />
			<arg value="js" />
			<arg value="--preserve-semi" />
			<arg value="-o" />
			<arg value="${jsSourceDir}\library.min.js" />
			<arg value="${jsSourceDir}\library.js" />
		</java>

The task java executes the Java command line for the default installed JVM. Notice the attributes used here. The first is jar. This attribute specifies the name of the JAR file to use. We’ve passed the property compressorJar, which as we saw above contains the full path to our YUI compressor JAR. Also notice that to run a JAR file we need to tell ANT to “fork” a new process. This is done by providing the fork attribute and set it to true. I am also setting the failonerror attribute to true so that if the JAR file returns a non-zero value the ANT script will halt with an error.

From here the YUI Compressor has a good number of arguments it can take to customize the minifcation experience. What I’ve done here is tell it to add line breaks at 4000 characters (–line-break 4000), the type of file is a JavaScript file (–type js), to preserve excess semicolons (–preserve-semi), and that we have an output file specified. The final argument is the input file.

After this we do the same to the CSS. Notice the lack of the –preserve-semi argument. That argument does not apply to CSS minification.

1
2
3
4
5
6
7
8
9
		<java jar="${compressorJar}" fork="true" failonerror="true">
			<arg value="--line-break" />
			<arg value="4000" />
			<arg value="--type" />
			<arg value="css" />
			<arg value="-o" />
			<arg value="${cssSourceDir}\style.min.css" />
			<arg value="${cssSourceDir}\style.css" />
		</java>

Below is the script in its full glory. Happy coding!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<project name="Minify JS and CSS" default="minify" basedir=".">
	<description>
		ANT build script to automate minification of library.js
		and style.css.
	</description>
 
	<property name="app" value="app-folder" />
	<property name="compressorJar" value="\\devpath\yui-compressor\build\yuicompressor-2.4.2.jar" />
	<property name="jsSourceDir" value="\\devpath\${app}\js" />
	<property name="cssSourceDir" value="\\devpath\${app}\css" />
 
	<target name="minify">
		<echo message="Starting minification process." />
 
		<echo message="Minifying JS..." />
		<java jar="${compressorJar}" fork="true" failonerror="true">
			<arg value="--line-break" />
			<arg value="4000" />
			<arg value="--type" />
			<arg value="js" />
			<arg value="--preserve-semi" />
			<arg value="-o" />
			<arg value="${jsSourceDir}\library.min.js" />
			<arg value="${jsSourceDir}\library.js" />
		</java>
 
		<echo message="Minifying CSS..." />
		<java jar="${compressorJar}" fork="true" failonerror="true">
			<arg value="--line-break" />
			<arg value="4000" />
			<arg value="--type" />
			<arg value="css" />
			<arg value="-o" />
			<arg value="${cssSourceDir}\style.min.css" />
			<arg value="${cssSourceDir}\style.css" />
		</java>
	</target>
 
</project>

Related Posts

No related posts.

  1. Jamie Krug says:

    Wow, I was literally planning to do this today! Thanks for saving me some time ;-)

    If you want to take this a step further, to make it a bit more flexible, you could loop over an entire directory to minify all *.js and *.css files. You might use an expression for the output file by just appending a “-min” before the extension, or maybe a separate directory for minified versions.

    Also, to simplify the YUI Compressor args slightly, the –type option is only required if the input file does not have a .js or .css extension.

    Thanks again for sharing!

  2. Adam Presley says:

    You are welcome! Yeah, you can definitely iterate over whole directories to minify all your JS and CSS. In this case we have only two JS files. One is a big, already minified mashup of jQuery, jQuery UI, and other libraries, and the other is our actual code. And the YUI compressor is one of the better ones out there. Great tool.

  3. Jesse Roach says:

    Nice! I just took that script and modified it to iterate over some directories and do a bunch minifizing…err minification. Very cool! Thanks for the ANT introduction. Fun stuff.

    What would be cool was if there was a way to minify a bunch of files into one file through this process. There probably is a way, but I have no idea what it is.

  4. I do something similar. I have an order.txt file, which ant uses to concatenate all the scripts that are part of my javascript project into a single file (order.txt is necessary because the concat order is important). The resulting file is copied to a debug version, and then YUI run against it to create the release version. Should we run into an error, we just switch the call to point to our debug version, and the line numbers make sense again. :)