日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2014年5月15日木曜日

Closure Compiler:コンパイルしたらJavaScriptの実行時にエラーが出るようになった。コードの順番を変えたら正常に動作した

イントロダクション

JavaScriptで記載したソースコードの圧縮・最適化のために、Google Closure Compilerを使用しています。

今回は、Google Closure Compiler でコンパイルする前のソースコードでは正常に動作していたものが、コンパイル後のソースコードでは、実行途中でエラーが出てしまった事例を紹介します。



コード

コンパイルに使用したコードを一部抜粋します。

function generateReferenceLink() {
    /* --- 省略 --- */
    if (currentMode == "single") {
        /* --- 省略 --- */
    } else {

        /* --- 省略 --- */

        genFromUri(uri_list[list_count], genNext);
        function genNext() {

            // 全ての生成が終わるまで繰り返し実行
            list_count++;
            if (uri_list.length > list_count) {
                genFromUri(uri_list[list_count], genNext);
            } else {
                finish();
            }
        }
    }
    /* --- 省略 --- */
}

コンパイル方法

コンパイルは以下のコマンドにて、コンパイルしました。
java -jar C:\tool\compiler-latest\compiler.jar --charset utf8 --js main.js --js_output_file main_compiled.js

実行結果

以下のように、TypeError が発生してしまいました。

  1. Uncaught TypeError: undefined is not a function main_compiled.js:2


順序を変えたコード

コンパイル後のソースコードの場合、圧縮・最適化によって難読化されているため、原因箇所を突き止めるのは容易なことではありません。

しかしながら、今回はいろいろな動作を外部から与えることで、原因となっているであろう箇所を上記の抜粋したソースコードの箇所であることを突き止めることが出来ました。

上記エラーを踏まえて、Closure Compiler の最適化に起因するだろうという推測の元、ソースコードの順番を入れ替えて、再度コンパイルしてみることにしました。


以下の赤いテキスト背景色の部分のコードと、青いテキスト背景色の部分のコードの順番を入れ替えました。

function generateReferenceLink() {
    /* --- 省略 --- */
    if (currentMode == "single") {
        /* --- 省略 --- */
    } else {

        /* --- 省略 --- */

        function genNext() {

            // 全ての生成が終わるまで繰り返し実行
            list_count++;
            if (uri_list.length > list_count) {
                genFromUri(uri_list[list_count], genNext);
            } else {
                finish();
            }
        }
        genFromUri(uri_list[list_count], genNext);
    }
    /* --- 省略 --- */
}


その結果、今度は実行途中にエラーが出ることなく実行できました。


何が違うのか?

Google Closure Compiler でコンパイルした結果の diff をとり、異なる部分を抜き出しました。

エラーあり:h=0;a(k[h],l);var l=function(){h++;k.length>h?a(k[h],l):f()}}}
エラーなし:h=0,l=function(){h++;k.length>h?a(k[h],l):f()};a(k[h],l)}}


んー・・・、この違いを見ても、上記のエラーが出る原因らしきところがわかりませんね。。。

まとめ

Google Closure Compiler でコンパイルしたソースコードを実行した結果、途中でエラーが出てしまった場合には、ソースコードの並び順を変えると正常に動くようになる時があります。





関連記事

関連記事を読み込み中...

同じラベルの記事を読み込み中...