私があなたの質問を正しく理解していれば、threejs.js に依存する awesomeGame.js をコンパイルしようとしていますが、クロージャの名前変更プロセスによって threejs.js への参照が壊れています。
自動化された extern スクリプトにはおそらく多くの開発が必要であり、堅牢なソリューションではない可能性があることに同意します。
私のプロジェクトには非常によく似た問題がありました。私は2つの可能な解決策を提供できます。それぞれにトレードオフがあります。私は個人的に threejs ユーザーではありません。ここでは一般的な規則のみを説明します。
1) ウィンドウ オブジェクトから開始し、ブラケット構文を使用して必要なオブジェクトを呼び出します。
このディスカッションによると、ライブラリが実行されてそのルート オブジェクトがグローバル コンテキストに配置された後、- から開始して見つけることができwindow
、ウィンドウ オブジェクトの名前は変更されません。さらに、ブラケット構文の名前が変更されることはありません。THREE
したがって、コンパイルされたコードはatwindow['THREE']
およびTHREE.Geometry
atなどを見つけることができます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 とクロージャの互換性については活発に議論されています。
とにかく、これがあなたの質問に答えてくれることを願っています。私が的外れである場合は返信してください。「インクルード/モジュール化」フレームワークもたくさんあります。多分誰かがその主題に記入することができます.