高機能な JavaScript 圧縮ツール「jsjuicer」
JavaScript を使った Web アプリケーションを公開する際にほぼ必須となるツールが JavaScript Obfuscator 、いわゆる JavaScript 圧縮(難読化)ツールです。とくに Ajax を活用したサイトでは JavScript ファイルも大きくなりがちなので、できるだけコンパクトにまとめてページのロード時間を短縮したいところです。そんなわけで、私も Infosketch を公開する際にいろいろ試しまして、本日ご紹介する jsjuicer を使うことにしました。
この jsjuicer は Web 関連のツールでは珍しく C++ で組まれたコマンドラインプログラムとなっています。そのため使い始めは少々面倒ですが、 make などによる自動化がやりやすいというのは大きな利点です。他のツールにはない便利な機能もいくつか実装されていますので、実用的な JavaScript 圧縮ツールをお探しの方は、ぜひ使ってみてください。
インストール
OS が Windows であれば、 jsjuicer のインストールは簡単です。公式ページで Win32 用にコンパイルされたバイナリが配布されているので(最初のほうの「A win32 version is available.」というあたり)、それをダウンロードしてパスの通った場所にコピーするだけです。
Windows 以外では、自分でソースからコンパイルする必要があります。と言っても、なにも難しいことはありません。公式ページの上部に C++ ソースへのリンクがあるので(サイトロゴ右下の [C++ code])それをダウンロードし、以下のコマンドを実行するだけです(ファイル名は適宜変更してください)。
g++ -O2 -o jsjuicer jsjuicer_1_2.cpp
これで jsjuicer という実行ファイルができるはずなので、それをパスの通ったディレクトリにコピーしてください。 Cygwin でもこれでコンパイルできました。
いずれの方法を使ったにせよ、作業が終わったら以下のコマンドを実行して、正常に実行できることを確認してください。
jsjuicer -h
jsjuicer のヘルプが表示されれば、 jsjuicer が利用可能な状態になっています。そうそう、なぜか Win32 用のコンパイル済みバイナリは "js_juicer.exe" という名前になっているので、適宜読み替えてください。以下、実行ファイル名は "jsjuicer" で統一します。
使ってみる
jsjuicer の基本的な使い方は以下のとおりです。オプションの "-sm" の意味は後でご説明します。
jsjuicer -sm 出力ファイル 入力ファイル
例えば、以下の内容の "example.js" があったとします。
function foo(operand_a, operand_b) { // add operand_a and operand_b return operand_a + operand_b; }
これを圧縮して "example_min.js" に出力するには、以下のようにします。
jsjuicer -sm example_min.js example.js
すると、出力される "example_min.js" はこうなります。
function foo(operand_a,operand_b) {return operand_a+operand_b;}
元が短いのでさほど恩恵はありませんが、コメントや不要なスペースが取り除かれているのがお分かりいただけるかと思います。
ちなみに、入力ファイルを複数指定すると、それらをすべて結合した後に圧縮して出力します。開発時には複数のファイルに分けておき、デプロイ時に結合するような使い方に便利です。
さらに使いこなす
jsjuicer には、コメントや空白を取り除く以外にもいくつか機能があります。それらを知るために、まずは完全なコマンドラインの書式をご紹介しましょう。
jsjuicer [オプション] [コメント] [出力ファイル] [入力ファイル]
コメント は "-c" オプションを付けたときのみ指定できます。また、出力ファイルや入力ファイルを省略したときは、それぞれ標準出力や標準入力が使用されます。利用可能なオプションは以下のとおりです。
オプション | 機能 |
---|---|
-s | コメントを取り除く |
-d | ";;;" で始まる行をデバッグ用コードとみなして取り除く |
-m | 不要な空白やコントロールキャラクタを削除する |
-o | "$" で始まるシンボルを短い名前に置き換える |
-c | 出力ファイルの最初にコメントを出力する |
-h | 使い方の説明を表示する |
複数のオプションを指定するときは、先ほどの例のように "-sm" などと指定します。 "-s", "-m", "-h" の機能は説明するまでもないでしょう。 "-c" はコメントで指定した文字列を出力ファイルの先頭に挿入するだけです。残りの "-d" と "-o" はなかなか興味深い機能なので、少し詳しくご紹介しましょう。
シンボルを短縮する(-o オプション)
"-o" オプションを指定すると、 "$" で始まる変数名や関数名などのシンボルを、 "$数値" という短い名前に変換してくれます。例えば、先ほどの例を少し変更して、以下のソースを圧縮してみましょう。
function foo($operand_a, $operand_b) { // add $operand_a and $operand_b return $operand_a + $operand_b; }
これを "-o" オプション付きで圧縮します。
jsjuicer -smo example_min.js example.js
すると、結果は以下のようになります。
function foo($0,$1) {return $0+$1;}
ずいぶん短くなりましたね!(゜▽゜)
JavaScript のソースを書くときは、ファイルサイズの膨張を防ぐために短い変数名を使うのが一般的です。しかし、この機能を使えば、最終的なファイルサイズを抑えつつわかりやすい変数名を使うことができ、メンテナンス性が大きく向上します。ブラウザサイドで短縮名を展開するような方法と違って実行時の負荷が増えることもありませんので、とても実用的な機能だと思います。
ただし、名前と数値の対応が一致するのは同じソースファイル内だけという点には、注意が必要です。他のファイルから参照されるようなパブリックシンボルには "$" を付けてはいけません。私の場合、ローカル変数やクラスのプライベートメンバのみ "$" を付けることで対処しています。派生クラスも含めて同一ファイルに収めなくてはいけませんが、プライベートメンバとパブリックメンバが明確に分けられるという良い副作用もあり、なかなかお勧めですよ。
デバッグ用のコードを削除する(-d オプション)
JavaScript に限った話ではありませんが、プログラムの開発時にはデバッグ用のコードを挿入することがよくあります。 C++ や Java といったコンパイル系の言語であればプリプロセッサでそれらを簡単に削除できますが、 JavaScript ではそうもいきません。フィルターを自作すればいいのですが、ちょっと面倒ですよね。しかし、 jsjuicer を使っていればそんな必要もありません。 ";;;" で始まる行をデバッグ用コードと考えて、自動的に削除する機能があります。
例えば、先ほどのコードに今度はログ出力を加えてみましょう。
function foo($operand_a, $operand_b) { // add $operand_a and $operand_b ;;; console.log('foo is called.'); return $operand_a + $operand_b; }
ログ出力の行が ";;;" で始まっているのがポイントです。これを "-d" オプション付きで圧縮してみましょう。
jsjuicer -smod example_min.js example.js
すると、結果は以下のようになります。
function foo($0,$1) {return $0+$1;}
ログ出力のコードが跡形もなく削除され、ひとつ前の結果とまったく同じものになっています。これなら好きなだけデバッグコードを差し込むことができますね。通常のコードとの区別も明確になって、一石二鳥です。
Prototype.js などとの相性を改善
jsjuicer の "-o" オプションはとても便利なのですが、大きな欠点がひとつあります。それは、 Prototype.js などの "$" で始まるシンボルを定義するライブラリが使えなくなってしまうということです。 "RegExp.$1" なんてのもダメですね。私は後者を良く使うので、これはいただけません。
そこで、ソースをちょっと改造して "$" + 1 文字のシンボルはそのまま出力するようにしてみました。どうせこの長さは短縮できませんし(笑)。これなら "RegExp.$1" はもちろん、 Prototype.js の "$A" とかも使えるはずです。以下にソースを置いておきましたので、ご自由にお使いください。ライセンスはオリジナルと同じ New BSD License でお願いします。
http://webos-goodies.googlecode.com/svn/trunk/blog...
ちなみに、シンボルの短縮は "obfuscate_identifier" という関数で行われていて、そこを変更するだけで条件を自由にカスタマイズできます。せっかくソースが公開されているので、おおいに活用しましょう。
以上、本日はコマンドラインで使える JavaScript 圧縮ツール jsjuicer をご紹介しました。コーディング時の規則を決め打ちすることで便利な機能を提供するという考え方は、 Ruby on Rails を彷彿とさせますね。とても優れたツールだと思います。ブラウザ上で簡単に試せる Web バージョンもありますので、ぜひ一度お試しくださいませ。
詳しくはこちらの記事をどうぞ!
この記事にコメントする