最近になってGoogleのClosure Compiler Serviceを良く使うようになった。今まで使っていたYUI Compressorと比較すると、複数のJavaScriptファイルをまとめて圧縮出来ることと圧縮にとどまらない最適化を行うことも出来ることがメリットで、CSSの圧縮には対応していないことがデメリット。ウェブのUIで圧縮するのは面倒になってきたので、REST APIを利用してウェブのUIと同じようにコメントで設定を記述してコンパイルするPerlスクリプトを書いてみた。タイトル長い!
#!/usr/bin/perl
# gccs.pl - Compile your JavaScript code with Google Closure Compiler Service
# Usage: gccs.pl < <original file> > <compiled file>
# Author: Kyo Nagashima <kyo@hail2u.net>, http://hail2u.net/
# License: MIT license (http://opensource.org/licenses/mit-license.php)
# Modified: 2009-12-12T00:57:02+09:00
use strict;
use warnings;
use JSON;
use LWP::UserAgent;
my @params = (
"output_info", "compiled_code",
"output_format", "json",
);
&main;
exit;
sub main {
my @code = <STDIN>;
push @params, "js_code", join("", @code);
my $idx = 0;
my $found_metadata = 0;
while (my $line = $code[$idx++]) {
if ($line =~ /^\/\/ ==ClosureCompiler==/) {
$found_metadata = 1;
last;
}
}
if ($found_metadata) {
while (my $line = $code[$idx++]) {
if ($line =~ /^\/\/ ==\/ClosureCompiler==/) {
last;
} elsif ($line =~ /^\/\/ @(\S+)\s*(.*)$/) {
push @params, $1, $2;
}
}
}
&compile(@params);
}
sub compile {
my $ua = LWP::UserAgent->new;
my $res = $ua->post("http://closure-compiler.appspot.com/compile", \@_);
if ($res->is_success) {
my $c = from_json($res->decoded_content);
if (defined $c->{"serverErrors"}) {
foreach (@{$c->{"serverErrors"}}) {
warn "Error(" . $_->{"code"} . "): " . $_->{"error"};
}
die "Failed to compile";
} else {
print $c->{"compiledCode"};
}
} else {
die $res->status_line;
}
}
使い方は、
$ gccs.pl < original.js > compiled.js
コンパイルするfoobar.jsにはコンパイル設定を書くこともできる(設定を書かなくても圧縮される)。設定は以下のようにコメントとして記述(ウェブUIと同じ)。
// ==ClosureCompiler==
// @code_url http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==
$(function () {
var who = "Google Closure Compiler Service";
alert("Hello " + who + "!");
});
細かい設定はAPIリファレンスを参照。code_url
はいくつでも指定できる。compilation_level
はデフォルトでSIMPLE_OPTIMIZATIONS
に設定されているので省略可能。パラメータは丸投げなのでリファレンスに載っていない適当なパラメータなども設定できてしまうが、実害はないと思う。結果がJSONで返ってくるとみなしてパースしているので、output_format
は指定しない方が良い。また警告やエラーの出力にはまったく対応していないのでoutput_info
やwarning_level
を指定しても無意味。
foobar.jsには設定だけ書いても構わない。その場合はcode_url
が必須になる。
// ==ClosureCompiler==
// @code_url http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js
// @code_url http://hail2u.net/scripts/prettify/lang-css.js
// @code_url http://hail2u.net/scripts/prettify/loader.js
// ==/ClosureCompiler==
以上のように書いただけでもちゃんとコンパイルされる。
Vimから簡単に使えるように$MYVIMRC
には以下のように書いた。
" Compile JavaScript file with Google Closure Compiler Service
" :GCCS [<path>]
command! -nargs=? -complete=file GCCS :call s:CompileScript('<args>')
function! s:CompileScript(file)
if a:file == ''
silent normal ggVG
'<,'>!perl -S gccs.pl
silent normal V
else
execute '!perl -S gccs.pl < ' . expand('%') . ' > ' . a:file
endif
endfunction
コマンドGCCS
にファイルのパスが渡されたらそのファイルに出力、そうでない場合は全選択して差し替えるというもの。