Skip to content

Instantly share code, notes, and snippets.

@nikopol
Created October 15, 2012 14:27
Show Gist options
  • Save nikopol/3892746 to your computer and use it in GitHub Desktop.
Save nikopol/3892746 to your computer and use it in GitHub Desktop.
js minifier [file.js [file.min.js]]
#!/usr/bin/env perl
#js minifier using google clojure WS api
#usages:
#./jsmin < file.js > file.min.js #input=stdin output=stdout
#./jsmin file.js #input=file.js output=file.min.js
#./jsmin file.js file.min.js #input=file.js output=file.min.js
use strict;
use warnings;
use JSON;
use LWP::UserAgent;
sub js_minify {
my $js = shift;
my $len = length $js;
my $ua = LWP::UserAgent->new;
my $res = $ua->post(
'http://closure-compiler.appspot.com/compile', [
'output_info' => 'compiled_code',
'output_info' => 'errors',
output_format => 'json',
warning_level => 'quiet',
#compilation_level => 'advanced_optimizations',
js_code => $js,
]
);
die $res->status_line,"\n" unless $res->is_success;
my $c = from_json($res->decoded_content);
if(exists $c->{serverErrors}){
warn 'ERROR #',$_->{'code'},': ',$_->{error},"\n"
foreach @{$c->{serverErrors}};
die "break on error\n";
}
if($c->{errors} && @{$c->{errors}}){
warn $_->{error},' line ',$_->{lineno},' near ',$_->{line},"\n"
foreach @{$c->{errors}};
die "break on error\n";
}
if($c->{compiledCode}) {
$js = $c->{compiledCode};
$js =~ s/[\r\n]+//;
my $zip = length $js;
}
$js
}
my $read = 0;
my $write = 0;
my $in;
my $out;
my $head = 1;
die "$0 [file.js [file.min.js]]\nby default stdin and stdout\n" if join(' ',@ARGV) =~ /-h/i;
my $fin = '/dev/stdin';
my $fout = '/dev/stdout';
if( @ARGV ) {
$fin = shift @ARGV;
die "$fin not readable\n" unless -r $fin;
if( @ARGV ) {
$fout = shift @ARGV;
} else {
$fout = $fin;
$fout =~ s/\.js$/.min.js/i;
$fout = $fin.'.min.js' if $fout eq $fin;
}
}
open(my $hin, '<', $fin) or die "error opening $fin as input: $!\n";
open(my $hout, '>', $fout) or die "error opening $fout as output: $!\n";
for my $l ( <$hin> ) {
$read += length $l;
if( $head && $l =~ m|^//| ) {
$out .= $l;
} else {
$head = 0;
$in .= $l;
}
}
close $hin;
$out .= js_minify($in) if length($in);
$write = length($out);
print $hout $out,"\n";
close $hout;
warn "minified from $read to $write (",$read?int(100*($read-$write)/$read):'?',"%)\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment