Perl Script to combine css/js using yui compressor

Yui Compressor is an awesome tool if you want to compress your css and (possibly obfuscate) js. However if you are anyone like me who would create a single css file for each Object / module (Restified CSS, a term that I use to define the use of a single css file for each object), you can soon endup having several css files, which you would want to be combined before put up on the production box.

According to the Yahoo!’s exceptional performance website you would want to reduce the number of HTTP requests on your page and this is done by having a single css and a single js file. Now the problem is with yui compressor you cannot pass multiple files as an argument so you need to compress and combine at the same time.

I quickly wrote down this Perl script (as i have been writing Perl scripts all day since morning) which will allow you to do the same. The order of files included is sometimes important esp with css (if you are taking up after someone else’s work). You would obviously need to configure this script accordingly to your env before you can execute it.

The syntax for running it is

$perl yui_compressor.pl <css|js>

and it outputs (for css files)

painthead-lm:css rpandit$ perl compress.pl css
Adding reset-fonts.css ...
Adding backend.css ...
Adding bought.css ...
Adding cart.css ...
Adding common.css ...
Adding layout.css ...
Adding main.css ...
Adding notice.css ...
Adding pager.css ...
Adding paypal.css ...
Adding search.css ...
Adding sfGuard.css ...
Adding username.css ...
Adding website.css ...
Adding websites.css ...
Saved 20090128185647.css

So here’s the script that goes with it:

#!/usr/bin/perl
$css_base_path = '';      #absolute path for the css files or relative to where the
                          #script is executed from

$js_base_path  = '';      #absolute path for the js files or relative to where the
                          #script is executed from

# css files in the order in which you would like them to be included
@cssfiles = (
                'reset-fonts.css', 'backend.css', 'bought.css', 'cart.css', 'common.css',
                'layout.css', 'main.css', 'notice.css', 'pager.css', 'paypal.css',
                'search.css', 'sfGuard.css', 'username.css', 'website.css', 'websites.css'
            );

@jssfiles = ();

#------- end of user configuration ------

if (scalar @ARGV ne 1)  {
  print "Error: Type not defined (css/js)\n";
  print "Syntax: $0 <css|js>\n\n";
  exit();
}
$type = $ARGV[0];

# grab the current time
my @now = localtime();

# rearrange the following to suit your stamping needs.
# it currently generates YYYYMMDDhhmmss
my $timeStamp = sprintf("%04d%02d%02d%02d%02d%02d",
                        $now[5]+1900, $now[4]+1, $now[3],
                        $now[2],      $now[1],   $now[0]);
#path for java
my $java           = '/usr/bin/java';
my $yuicompressor  = '/Users/rpandit/tools/yuicompressor-2.3.5/build/yuicompressor-2.3.5.jar';

my @array_to_process = ();
if ('css' eq $type) {
  @array_to_process = @cssfiles;
} elsif ('js' eq $type) {
  @array_to_process = @jssfiles;
}

foreach(@array_to_process) {
  `$java -jar $yuicompressor $_ >> $timeStamp.$type`;
  print "Adding " . $_ . " ...\n";
}
print "Saved $timeStamp.type\n\n";

About rp

Architect for large, highly scalable LAMP applications and Technical Manager with special focus on metrics based continuous improvement of teams and products. Rajat has close to a decade of experience of a very wide range of skills related to infrastructure, middleware, app servers all the way to front-end technologies and software development methodologies including agile, iterative waterfall, waterfall as well as ah-hoc startup using the right approach in the right context to reduce time to market.