2

まず、私はこの SO の質問externs extractor hereを認識しています。

ThreeJSを使用して最初のゲーム プロジェクトに取り組んでいます。モジュール方式でビルドしたので、最終的にはGoogle の Closure Compilerを使用して結果をパックするつもりでした。ちょっとしたテストでは、(高度な最適化を使用して) コンパイルすると、構築されたオブジェクトのメソッドとプロパティも縮小されることが示されましTHREE.GeometryTHREE.Color

生成された externs ファイルを確認すると、これはTHREE.Color78 行目 (ThreeJS r60) で見つけたものです。

"Color": function () {},

明らかにメソッドとプロパティが不足しているため、Closure Compiler はこれらの名前を変更する必要がないことを認識しません。

別のファイルで露出を定義し、ソースと一緒にコンパイルするという別の解決策がありました。これは問題なく動作しますが、使用される各メソッドとプロパティをこのように定義するには多くの手作業が必要です。また、これはハック的な回避策です。Closure Compiler は、オブジェクト上に出現するこれらの名前の名前をまったく変更しないという単純な手段に頼っています。

たとえば、これらはすべて同じ効果があります。

/** @expose */
THREE.Geometry.vertices;

/** @expose */
THREE.vertices;

/** @expose */
Object.vertices;

window.vertices = function() {
    console.log("foo");
};

window.vertices名前は変更されません。結果として、これは理想的なソリューションではありません。

実際の問題は、Closure Compiler でこれができるかどうかです。それとも、そのような依存関係をコンパイルに組み込み、使用するすべてのメソッドとプロパティの名前を変更する必要がありますか?

4

1 に答える 1

2

私があなたの質問を正しく理解していれば、threejs.js に依存する awesomeGame.js をコンパイルしようとしていますが、クロージャの名前変更プロセスによって threejs.js への参照が壊れています。

自動化された extern スクリプトにはおそらく多くの開発が必要であり、堅牢なソリューションではない可能性があることに同意します。

私のプロジェクトには非常によく似た問題がありました。私は2つの可能な解決策を提供できます。それぞれにトレードオフがあります。私は個人的に threejs ユーザーではありません。ここでは一般的な規則のみを説明します。

1) ウィンドウ オブジェクトから開始し、ブラケット構文を使用して必要なオブジェクトを呼び出します。

このディスカッションによると、ライブラリが実行されてそのルート オブジェクトがグローバル コンテキストに配置された後、- から開始して見つけることができwindow、ウィンドウ オブジェクトの名前は変更されません。さらに、ブラケット構文の名前が変更されることはありません。THREEしたがって、コンパイルされたコードはatwindow['THREE']およびTHREE.Geometryatなどを見つけることができますwindow['THREE']['Geometry']。また、jQuery は window['jQuery'] で、アンダースコアは window['_'] で見つかります。

コンパイルされたコード (たとえば threejs.js) から外部オブジェクトまたは関数にアクセスする必要がある場合はいつでも、次のようにファイルの先頭にいくつかのグローバル定義を記述することをお勧めします。

// awesomeGame.js:

// global defines:
var three_vertex        = window['THREE']['Geometry']['vertex'],
    three_rectangle     = window['THREE']['Geometry']['rectangle'],
    three_crossproduct  = window['THREE']['Math']['crossproduct'],
    jquery_ajax         = window['jQuery']['ajax'];

// game assets:
var myVertex         = new three_vertex(10,10),
    myRectangle      = new three_rectangle(10,10,10,10);

// do stuff:
console.log(myVertex['x'] + ' ' + myVertex['y']);
console.log(three_crossproduct(myVertex, myVertex));

myRectangle['paint']('black');

上記をプリティ/アドバンスト モードのコンパイラ サービスに貼り付けると、次の結果が得られます。

var a = window.THREE.Geometry.rectangle,
    b = window.THREE.Math.crossproduct,
    c = new window.THREE.Geometry.vertex(10, 10),
    d = new a(10, 10, 10, 10);

console.log(c.x + " " + c.y);
console.log(b(c, c));
d.paint("black");

良い点: threejs.js の完全な参照は、グローバル定義で 1 回だけ出力されます。それ以降、クロージャーはコンテナー 'a' または 'b' を代わりに出力します。したがって、説明した extern アプローチとは異なり、ほとんどの圧縮の利点が得られます。

欠点: threejs.js オブジェクトのメソッドとプロパティは、ブラケット構文で一貫して名前を付ける必要があります。['x'] プロパティと ['y'] プロパティ、および ['paint'] メソッドは、括弧で囲まれていなければ名前が変更されていることに注意してください。Closure を--warning_level=VERBOSEに設定し、エラーを監視して、JSC_INEXISTENT_PROPERTYそれらを括弧で囲みます。何かを忘れると、コンパイラーが思い出させてくれます。エラー参照

あなたのリンターがすべての括弧に動揺している場合--subは、「添え字を容認する」のように、で説得してください。すべての jsLint エラー/オプション

2) threejs.js と awesomeGame.js を連結して temp.js にする

別のアプローチ: すべてのソース ファイルを依存関係の順に連結してグランド一時ファイルにするビルド スクリプトを自分で設定します。Unix の場合、スクリプトは次のようになります。

#!/bin/bash
# build_and_run.sh
# get updates to google closure: http://code.google.com/p/closure-compiler/downloads/list
#
# local jslint:
# sudo apt-get install nodejs npm
# sudo npm jslint -g

rm temp.js
rm final.js

cat threejs.js \
    awesomeGame_moduleOne.js \
    awesomeGame_moduleTwo.js \
    > temp.js

# docs: http://www.jslint.com/lint.html

jslint  temp.js \
        --maxerr=50 --sloppy --white --sub --plusplus \
        --nomen --bitwise --browser \
        --predef unescape \
        --predef Uint8Array \
        --predef Blob

java    -jar                compiler-20130823.jar \
        --compilation_level ADVANCED_OPTIMIZATIONS \
        --formatting        pretty_print \
        --language_in=ECMASCRIPT5 \
        --js                temp.js \
        --js_output_file    final.js

#maybe
nodejs  final.js

# or
# https://developers.google.com/chrome/web-store/docs/get_started_simple

chromium --load-and-launch-app=./

# rinse, repeat

良い点: 括弧なし、定義なし、エクストレンなし、ミドルウェアなし。Googleの閉鎖はすべてを見ています。最終製品の最大圧縮。出荷プロジェクトの完全なリンティングも同様です (元の分割されたソース ファイルをスキャンすると、リンターが混乱する可能性があります)。単一の統合ファイルを出荷します。

欠点: 上流のソース コードに没頭する。これは、あなたにとって同意できる場合とそうでない場合があります。アップストリームのソースを lint すると、特にコード スタイルをアップストリームに押し付けたくなります。抵抗、抵抗。一方で、依存しているミドルウェアを知っていることには利点があります。

master.js ファイルのデバッグも必要です。final.js の行番号が報告され、読み取り時にソース ファイルを特定する必要があるためです。きれいなモード、より穏やかなコンパイル設定、 @preserveコメント、および多くを使用console.logすると、それを処理できます。

最後に、threejs での優先順位とコード規則によっては、Closure でのコンパイルがサポートされないか、動作が微妙に変わる可能性があります。その場合は、このオプションを除外してください。たとえば、 jQuery とクロージャの互換性については活発に議論されています。


とにかく、これがあなたの質問に答えてくれることを願っています。私が的外れである場合は返信してください。「インクルード/モジュール化」フレームワークもたくさんあります。多分誰かがその主題に記入することができます.

于 2013-09-12T17:49:51.937 に答える