亜細亜ノ蛾 - Weblog

[SiteSearch Google]

November 25, 2007

「JavaScript ファイルの縮小(Minify)」が なぜ難しいか?

[ad]

JavaScript を縮小・圧縮したい!

PHP の勉強も兼ねて、

「JavaScript ファイルを自動的に縮小(Minify)して、(gzip)圧縮する」

というスクリプトを作っています──と何度も書いて来ましたが、

結論: \(^o^)/ 無理

という、残念な結果に終わりそうです(8 割方 予想が付いていたけど)。

今回は、それがなぜ難しいのか という話と、/packer/ は やっぱり凄い! という話です。

目標

やりたいこと:

  • PHP4 で作る
  • 自動で処理する
  • JavaScript ファイルから
    • コメントを削除
    • 余分な空白・改行を削除

たったこれだけのことですが、じつは ものすごく難しいです。ちなみに、「PHP4」で、というのは、ただ単に ここのサーバで動いているのが PHP4 だから、というだけの理由です。PHP5 だと、類似のスクリプトはいくつかあるのですが……。

「そんなの、2 分でできるよ」というひと向けに、下記の(わざとらしい)"sample.js" をどうぞ。

/***/

/**
 *  comment
 *  // comment
 */

/*@cc_on
//  http://d.hatena.ne.jp/amachang/20071010/1192012056
var doc = document;          // comment
eval('var document = doc');  // comment
@*/

/*@cc_on document.write('"IE!"\n'); @*/     // comment

var hoge = "/* hoge */\n";
var fuga = '"/* fuga */"\n';
var foo  = "//* foo *//\n";
var bar  = '"\'//* bar *//\'"\n';

document.write(hoge + fuga + foo + bar);

上記のコードを Minify すると、こうなるはずです。──そんなスクリプト、書けますか?

/*@cc_on var doc=document;eval('var document = doc');@*//*@cc_on document.write('"IE!"\n');@*/var hoge="/* hoge */\n";var fuga='"/* fuga */"\n';var foo="//* foo *//\n";var bar='"\'//* bar *//\'"\n';document.write(hoge+fuga+foo+bar);

難しいところ

"sample.js" は、正規表現の初心者には、じつは一行目からコメントにマッチさせるのが難しいです。

Effective Perl』の p.77-78 に、「C のコメントにマッチする正規表現」として、詳しい説明が載っています。

/***/ にもマッチさせるためには、

#/\*([^*]|\*[^/])*\*/#g;

ではダメで、

#/\*[^*]*\*+([^/*][^*]*\*+)*/#g;

と書く必要があります(「欲張らない」繰り返し演算子を使わない場合)。

その他に、クォーテーションの中はコメントを無視したり、いろいろ配慮する必要があって、かなりややこしい。

C と C++のコメントを除去する正規表現は、下記のページをどうぞ。

perlfaq6 - Regular Expressions 訳出 2005/11/2

JavaScript ならではの「条件付きコメント」

さて、C++ と JavaScript のコメント定義は似ているので、ほとんどが流用できるのですが──。

id:amachang の記事で、一気に有名になった、IE だけに実行可能なコメント、/*@cc_on @*/ を配慮する必要がありまして……。

一行で IE の JavaScript を高速化する方法 - IT戦記

通常のコメントは除去しても、この「条件付きコメント」は残す、そしてコメント内部の余分な空白は削除する──などが難しいです。

じっさい、PHP で JavaScript を圧縮するスクリプトは、この条件付きコメントあたりを考慮しているものが、かなり少ない(無い?)です。

「/packer/」が優秀

──と思っていたら、意外にも「/packer/」が優秀でした。

/packer/

「/packer/」といえば、「あー、あの eval で難読化(笑)するヤツ?」と言う人が多いです。「/packer/」で圧縮すると、スクリプトが遅くなる、という人も。

しかし、「encode」オプション(デフォルトは「Base62 encode」)をオフにすれば、

「余分な空白とコメントを除去、条件付きコメントは残す」

という処理だけを行います。これはかなり理想的な結果です。冒頭の縮小したスクリプトも、「/packer/」で作りました。

PHP 版「JavaScript Packer」はイマイチ

おお、これは!──と思って PHP 版の「JavaScript Packer」を試してみたら、これは条件付きコメントを丸ごとカットする、という仕様でした。

JavaScript Packer in PHP

オンライン版はバージョン 3.0 なのに、PHP 版はバージョンは 2.0.2 のエンジンを使っているからでしょうか。

かなり高速で縮小してくれるオンライン版は、じつは「JavaScript で JavaScript を縮小」しています。書いてあるコードもキレイでわかりやすいので、PHP に移植──を、だれか、してくれないかなぁ……(どこまでも他力本願)。

もしくは、「YUI Compressor」の PHP 版、とか。

Yahoo! UI Library: YUI Compressor

Google Adsense

コメント

コメントを投稿

"「JavaScript ファイルの縮小(Minify)」が なぜ難しいか?" にコメントを投稿することができます(別ウィンドウが開きます)。

トラックバック

このエントリーのトラックバックURL:

"「JavaScript ファイルの縮小(Minify)」が なぜ難しいか?"へのトラックバックはまだありません。

過去の記事

カテゴリィ一覧
  1. Movable Type
  2. その他
    1. アイデア
  3. ウェブ
    1. Weblog
    2. Webデザイン
    3. ちょっとイイ話
    4. へぇー(トリビア・雑学)
    5. オモロ
      1. オモロテキスト
      2. オモロニュース
      3. オモロ動画
      4. オモロ画像
    6. ニュース
  4. コンピュータ・エレクトロニクス
    1. PC
      1. Firefox
  5. マンガ・アニメ・ゲーム
    1. アニメ
      1. 新世紀エヴァンゲリオン
    2. オタク
    3. ゲーム
    4. マンガ
      1. 週刊少年ジャンプ
        1. DEATH NOTE
        2. HUNTER×HUNTER
        3. SKET DANCE
        4. バクマン。
  6. 本・音楽・映画・TV
    1. TV・芸能
    2. 映画
  7. 食・健康・生活
    1. ファッション
    2. 食べ物