Compiling Javascript

One problem I often encountered when doing some more adavanced JS development was the way of organising code. Having everything in a single file was a headache to work with, but then it was the expected result. Copy-pasting content from files into the “production” wasn’t really a solution. With help came Ant and YUI Compressor, two tools that made merging and minifing JS files a one click action.

I’m going to go through a simple example of merging all Javascript files in a given directory, minifing them and storing as a single file.

Ant’s main usage area is Java applications and it does not come with the PHP Netbeans edition. So all you need to do with Netbeans is go to Tools -> Plugins, search for the Ant plugin, and install it. Once you have that you will also need a YUI Compressor jar file.

We will create a /build folder in our project structure to keep things clean. Copy the YUI Compressor jar file there. You will also need to create an xml file where you specify how should your files be minified. Create a build.xml file in the /build folder with the following contents:

<project name="Minify JS" default="js.min" basedir="../">
    <property name="DEST_DIR" value="./js" description="Source folder" />
    <property name="SRC_DIR" value="./js/src" description="JavaScript source folder" />
    <property name="JS" value="all.js" description="JS output file" />
    <property name="JS_MIN" value="all.min.js" description="Minified JS output file" />
    
    <target name="js" description="Concatenate JavaScript source files">
        <concat destfile="${DEST_DIR}/${JS}">
            <fileset dir="${SRC_DIR}" includes="/">
            </fileset>
        </concat>
    </target>
 
    <target name="js.min" depends="js" description="Minimize JavaScript files">
        <apply executable="java" parallel="false" verbose="true" dest="${DEST_DIR}">
            <fileset dir="${DEST_DIR}">
                <include name="${JS}" />
            </fileset>
            <arg line="-jar" />
            <arg path="build/yuicompressor-2.4.7.jar" />
            <arg value="--charset" />
            <arg value="ANSI" />
            <arg value="-o" />
            <targetfile />
            <mapper type="glob" from="all.js" to="all.min.js" />
        </apply>
    </target>
</project>

The root of the XML document contains 2 important attributes:

<project name="Minify JS" default="js.min" basedir="../">

The name of the default target and the basedir. The default target is the default action which should be executed when running this XML file with ant, nothing to worry about at this point. Basedir allows us to set the root directory of our project. Since we have created our build file in a /build folder we want the basedir to point to /builds parent folder.

Below are a few properties we set:

<property name="DEST_DIR" value="./js" description="Source folder" />
<property name="SRC_DIR" value="./js/src" description="JavaScript source folder" />
<property name="JS" value="all.js" description="JS output file" />
<property name="JS_MIN" value="all.min.js" description="Minified JS output file" />

These represent the directory where we want the output JS file to be created, the directory where all the JS source files are placed, the name of the output JS file, and the name of it’s minified version.

We need to create a target to merge all the files into a single JS file:

<target name="js" description="Concatenate JavaScript source files">
    <concat destfile="${DEST_DIR}/${JS}">
        <fileset dir="${SRC_DIR}" includes="/">
        </fileset>
    </concat>
</target>

This target should be self explanatory. We merge all our source files into a single file in our destination directory. The fileset element is worth looking at in case you would like to use files matching some particular pattern. In this example all files from the earlier defined source directory will be used.

With the ant plugin you can right click build.xml in your project and select Run target -> js. A file with the contents of all of your source files should be created. Next target handles minifing the create file using YUI Compressor.

<target name="js.min" depends="js" description="Minimize JavaScript files">
    <apply executable="java" parallel="false" verbose="true" dest="${DEST_DIR}">
        <fileset dir="${DEST_DIR}">
            <include name="${JS}" />
        </fileset>
        <arg line="-jar" />
        <arg path="build/yuicompressor-2.4.7.jar" />
        <arg value="--charset" />
        <arg value="ANSI" />
        <arg value="-o" />
        <targetfile />
        <mapper type="glob" from="all.js" to="all.min.js" />
     </apply>
</target>

This targets contains a “depends” attribute pointing to “js” which means js target will be always run before this target. Please make sure you use a correct YUI Compressor path. In my case it is build/yuicompressor-2.4.7.jar but may change depending on the version you use. A mapper element defines which file to use as source for this target and which to use as output.

Again try right clicking on your build.xml, select Run target -> min.js. A minified version will be created.

Note: Avoid using 2.4.8 version of YUI Compressor on Windows – it has a file path bug resulting in errors.