Nate | Jul 15

0 comments

Using a bash script to minify and combine JavaScripts

One of Yahoo!'s best practices for speeding up your website is to combine files to reduce the number of HTTP requests. These days, I use JavaScript and jQuery on every single site I work with, and it's easy for me to get a bit lazy and forget to go to the trouble of combining all of my JS and minifying it. Plus, once I do that, every time I make a change to the JS, I have to do it all over again. It's kind of a pain.

So today I finally created a simple way to make this part of my workflow easier. I love using UNIX to work -- vim is the best text editor I've ever used, and I love the flexibility and power you have when using secure shell (SSH) to access a server rather than relying on an FTP program. I'm no veteran of the command line, but the great thing is that even very simple tools can improve your life as a web developer enormously.

I wanted a script that would quickly and easily grab all the JS files in a given directory (I always keep all my JS in a /scripts/ directory off the webroot), minify them using YUI Compressor (which dramatically reduces filesize), and combine them all into one file.

Here's how you can do the same thing.

Step #1: Download YUI Compressor and Put It On Your Server

Head over to the YUI Compressor site and download the zip file. It's a utility written in Java that is used from the command line - if you're a Mac user, you access that via terminal. You can use this either on your Mac or on a webhost to which you have SSH access.

On a UNIX system, you have a home directory -- on your Mac, that's the folder with your username, which you can access via Finder. If you're using terminal, the shortcut to your home directory is ~. So any time you type cd ~/, you will change the working directory to your home directory.

I made a folder in my home directory called /bin (mkdir ~/bin), and dropped in the whole YUI folder from the zip file I downloaded.

Step #2: Create a bash script

Then, I created a file called bundle.sh in my scripts directory.


#!/bin/bash

usage() {
    echo -e "\nbundle.sh FILE..."
    echo "Bundle (and minify) all JavaScripts in the current directory into a single file."
}

BUNDLEFILE=$1

if [ ! -n "$BUNDLEFILE" ]; then # Tests to see whether a bundlefile has been specified
    usage
    exit 0
fi

# Find YUI Compressor
if ! [ `find ~/. -type f -name yuicompressor\*.jar` ]
then
    echo "Unable to locate the YUI Compressor jar file!"
    exit 1
else 
    YUICOMPRESSOR=`find ~/. -type f -name yuicompressor\*.jar`
fi


# Minify JavaScripts

# If the output file already exists, we don't want to double its size. Remove it.
if [ -e "./$BUNDLEFILE" ]; then
    echo -e "Removing existing copy of $BUNDLEFILE."
    rm $BUNDLEFILE
fi

# Fetch external dependencies, like jQuery
echo -e "\nFetching a copy of jQuery v1.4.2..."
wget -O $BUNDLEFILE --progress=dot http://code.jquery.com/jquery-1.4.2.min.js

echo -e "\nMinifying JavaScripts..."
jslist=`find . -type f -name \*.js`

for jsfile in $jslist
do
    if [ ./$BUNDLEFILE != ${jsfile} ]
    then
        echo "Processing: ${jsfile}"
        java -jar ${YUICOMPRESSOR} ${jsfile} >> $BUNDLEFILE
    fi  
done

echo -e "\nDone."
exit 0

Step 3: Set Permissions

Use this command to change the permissions on your file so that you can execute it.

chmod u+rx bundle.sh

Step 4: Use the Script

You can use the script any time from within your scripts directory by typing

./bash.sh yourfile.min.js

BAM - you should have a file called yourfile.min.js (you can name this whatever you want) that has the minified contents of all your js files. If you update the OawvInRaf4 versions of your scripts, just run the command again -- it will remove and recreate your minified and combined version.

Conclusion

Bash scripting is, basically, a way to set up automated command line tasks. I used a script by Brad Kellett as a starting point for this one. The script uses wget to grab a copy of jQuery, then minifies each JS file in the working directory and appends it to the filename you typed in after bundle.sh.

If you don't happen to be a jQuery developer, you could change the script to fetch any script you wanted, or you could just remove those lines.

I'm going to work on universalizing this script further, but I was happy to make a simple tool for myself that turned an obnoxious task into a nearly effortless one. Any other designers out there have useful scripts they've made for themselves? Anyone have any suggestions on how to improve this one?

Leave a comment

Back to Top

The Design crew of PBS Interactive (listed in order of importance):

Meet the team