クロージャにテスト フックを追加できるように、関数からデバッグ コードを削除する方法を探しています。Google Closure Compiler advanced: remove code blocks at compile timeを読ん で、次のようにデバッグ コードの削除をテストしました。
/** @define {boolean} */
var DEBUG = true;
if (DEBUG) {
console.log('remove me');
}
を使用した単純な最適化は--define='DEBUG=false'
、これを に減らしvar DEBUG=!1;
ます。これにも同じことが当てはまります。
/** @const */
var DEBUG = false;
if (DEBUG) {
console.log('remove me');
}
問題が発生するのは、関数内でこの規則を使用することです。
/** @const */
var DEBUG = false;
function logMe() {
if (DEBUG) {
console.log('remove me');
}
}
これは次のようになります。
var DEBUG=!1;function logMe(){DEBUG&&console.log("remove me")};
私はそれがさらに減少すると予想します:
var DEBUG=!1;function logMe(){};
これが期待どおりに機能しない理由はありますか? 私は本当にデバッグ コードを削除するクリーンな方法を探しているだけで、高度な最適化に飛び込む準備ができていません。
アップデート
@John の回答に従って、私は独自のコンパイラを実装しましたが、次の構成がif (DEBUG) {}
a の場合にコードの内側と外側から削除されることがわかりました@define
。
CompilerOptions options = new CompilerOptions();
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
//options.setInlineConstantVars(true);
options.setInlineVariables(CompilerOptions.Reach.ALL);
options.setDefineToBooleanLiteral("DEBUG", false);
これは、次の制限がある 1 つのファイルに対しては十分に機能します。
- これは
var DEBUG
各ファイルで定義する必要がありますが、これは悪い習慣です。 - 複数のファイルを結合する場合、単一のファイルしか持つことが
var DEBUG
できないか、コンパイラがその周りを最適化できません。これは、各ファイルを個別にコンパイルしてマージすることで回避できます。 - 値はファイルの先頭で定義されているため、事前に値を受け取る柔軟性はありません。
var DEBUG
ファイルからすべての定義を削除し、実行前にソースまたは extern に挿入するというアイデアをいじりましたが、次の 2 つの問題に遭遇しました。
- extern で定義しても何もしないように見えます。
- コンパイルされていないコードでundefined
DEBUG
を指定すると、ブラウザで参照エラーがスローされます。
理想的なオプションはwindow.DEBUG
、参照エラーをスローしない test です。残念ながら、注入/** @const */ var window = {}; /** @const */ window.DEBUG = false;
はトップレベルで機能し、 を減らしますif (window.DEBUG) {}
が、関数に配置すると、最適化は実際には元に戻ります。
別のコンパイラ オプションが機能しない限り、本当に意味のある唯一のオプションは、window.DEBUG
コンパイル前に injectを使用し、 with を/** @const */ var DEBUG = false;
グローバルに置換することです。より良い方法はありますか?/\bwindow.DEBUG\b/
DEBUG