4

Googleクローズコンパイラを使用して、アプリケーションコードを1つの変数で(サーバとクライアントの両方で)実行する場所に基づいて分割しようとしています。この例では、サーバー上で呼び出されるものはすべてisServerSide varの背後にありますが、コードはクライアント用にコンパイルされています。だから私はapp.jsの内部falseにisServerSideを設定すると、コンパイラは、クライアントによって実行されないすべてのものを削除してみましょう...Googleクローズコンパイラ - externsに基づくデッドコードの削除

ます:

externs.jsの内部
goog.provide('my.app'); 
my.app.log = function(message) { 
    document.write(message); 
} 
my.app.initClientSide = function() { 
    my.app.log('hello client'); 
} 

my.app.initServerSide = function() { 
    my.app.log('hello server'); 
} 

if (isServerSide) { 
    my.app.log('initing server'); 
    my.app.initServerSide() 
}else my.app.initClientSide(); 

/** 
* @define {boolean} is server side? 
*/ 
var isServerSide=false; 

コマンド:

java -jar bin/compiler.jar --js closure-library/closure/goog/base.js --js app.js --externs externs.js --manage_closure_dependencies true --process_closure_primitives true --summary_detail_level 3 --warning_level VERBOSE --compilation_level=ADVANCED_OPTIMIZATIONS --closure_entry_point my.app 

予想される出力:

document.write("hello client"); 

実際の出力は:私は手動でapp.jsisServerSide=false;を入力した場合

isServerSide?(document.write("initing server"),document.write("hello server")):document.write("hello client"); 

その後、私はそれがこれにコンパイルするために得ることができます:私は設定してい思わせる

isServerSide=false;document.write("hello client"); 

私のexterns.jsが間違っている(または、私はちょうどどのようなexternsが実際に使用されるべきか理解していない)。

これを取得する方法についてのご意見はありますか?

+0

外部宣言は、外部名を確保し、機能/型シグネチャを定義するためのものです(例:[jQuery](http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.3.2.externs.js?r=66))、そうです私はコンパイラがその価値観に注意を払っているとは思わない。 'app.js'を' app_client.js'と 'app_server.js'に分割して、クライアント/サーバコードで常にそれぞれのバージョンを呼び出すことはできますか? – hyperslug

+0

@hyperslugによれば、externsは変数が外部スクリプトで定義されていることをコンパイラに示すことです。コンパイラは、その変数がその外部スクリプトによって設定されると仮定して、**無視します**。したがって、コンパイラーは、そのextern変数の値が何であるか分からないため、ifステートメントの2つのブランチのいずれか*を削除しないことがわかります。必要なのはあなたのスクリプト内の '@ define'です。そして、' --define'コンパイラスイッチを使ってそれをオン/オフします。この場合、期待される出力が得られます。 –

+0

ありがとうございました。ちょうど確認するために、両方とも言ったことは絶対に正しいです:) –

答えて

6

@define値は、コンパイラ呼び出しで直接設定することによって指定します。 エクスタンスは、ハイパーサーグのような異なる目的を果たします。

あなたはapp.jsに(あなたのexternから)@define定義を入れた後、次のようにコンパイラを呼び出すことによって期待される結果を達成:

java -jar compiler.jar \ 
--define "isServerSide=false" \ 
--js closure-library/closure/goog/base.js \ 
--js app.js \ 
--manage_closure_dependencies true \ 
--process_closure_primitives true \ 
--summary_detail_level 3 \ 
--warning_level VERBOSE \ 
--compilation_level=ADVANCED_OPTIMIZATIONS \ 
--closure_entry_point my.app 
+0

ありがとう、それはトリックでした。誰かが不思議に思っている場合、私は新しいファイル( 'isServerSide.js')を作成し、' my.app'の 'goog.require'を作成しました。そのようにして、私はアプリケーション・コードを定義文で混乱させるわけではありませんが、コンパイラcmdで 'define'を設定できます... –

関連する問題