当社は独自のWebアプリケーションを開発しています。 つまり、外部資金なしで:)これには賛否両論があります。 しかし、私がいつも好きで好きなのは、テクノロジー、アプローチ、ソリューションなど、何か新しいことを試す機会です。 何らかの理由で、プロジェクトのサイトに名前を付けることはできませんが、仕事中に得た経験を共有することはできます。
ユーザーに直接表示され、ユーザーと密接に連携するプロジェクトの部分を担当しているので、私の話はそれについてです)。
そもそも、読者が危機にwhatしているものを理解するために、私たちが「暗い」面に持っているものをお話ししたいと思います。 そして、Java、MySQL、Neo4J、Jetty、RabbitMQがあり、この長いpythonの最後にはnginxがあります。
Gcl
2010年の終わりに、「有効な」web-js部門である私たちは、以下のいくつかの理由で古いテンプレートエンジンを放棄し、新しいものに進み、私たちのクレイジープロジェクトの現実を実際に満たすことにしました。 問題は、その時点でウィジェットと場所(場所)の概念が既に実装されていたことでした。 私たちの理解では、ウィジェットはチャネルを介して通信するいくつかの独立した視覚要素です。 チャネルを介して、メッセージを送信し、特定のタイプのメッセージをサブスクライブできます。 ウィジェットは、順番に、それが家のどこにあるかを知りません-場所はこれに責任があります。 大きな問題は、ウィジェットがデータを視覚化する特定のパターンを定義したことです。 同じウィジェットをさまざまな場所で使用できますが、データをさまざまな方法で表示できるため、ユーザーはさまざまな方法でデータを操作できます。 しかし、古代のテンプレートエンジンに戻ります。 そのとき、すべてのテンプレートはWebストレージのクライアントにロードおよびキャッシュされました。これは、jsコードに特定の非同期性があったためです。ウィジェットの作成後、データが表示されるまでに時間がかかりました。 たとえば、テンプレートエンジンの多くの問題を解決する新しいソリューションを探していました。
- サイクルはありませんでした
- ローカライズの複雑さ(テキストに変数を挿入することは不可能でした)
- 条件と分岐はありませんでした。
その時点で既存のソリューションを分析し、Google Closure Library(GCL)を選択しました...はい、Googleがテクノロジーを提供していることも知りませんでしたが、その使用のためのツールは提供していません:)
その時までに、プロジェクトは以下で構成されていました。
- 〜500個のjsファイル
- 〜30 cssファイル
- 〜300パターン。
答えは、クロージャーが提供する統合アプローチにあります。 したかったのは:
jsコードは圧縮され、拡張モードで最適化されました
- デッドjsコードの削除
- cssは圧縮および検証されました
- テンプレートは、クライアント側でチェック、圧縮、保存されました。
- リソースを異なる言語に簡単に翻訳
その時点でネットワーク上にあったすべてのソリューションは1つのことを提供し、Googleは3つの関連ソリューションを提供しました。クロージャコンパイラ、クロージャテンプレート、クロージャスタイルシート。これらは別々に、そして一緒に機能します。 そして、彼らが一緒に働くとき、結果は単に驚くべきものです!
JSコードを変更する
最初に始めたのは、どこでもjs依存関係でした... goog.require ...それは長い時間で、約1か月かかりました。 その結果、新しいjsファイルとロジックの接続が単純化されました。依存関係を登録するだけで、システムは必要なコードを自動的にロードします。
Googleは、その技術を使用するためのツールを提供していませんが、開発者が直接(G +経由で)Eclipseで記述し、完全なクロージャーサポートを持っていると報告したため、Google自体にあります。
Eclipse用のスクリプトをビルドイベントの形式で作成しました。これは、jsを保存するたびに、クロージャーのdeps.js依存関係ファイルを更新しました。 当時は、プロジェクト全体(Tomcat、mysql、mqブローカーなど)が各開発者のマシンによって引き上げられ、6ギガバイトのメモリを消費し、プロジェクト全体を開始するのに約1.5〜2分必要でした。 nginxを介してjs、css、imgファイルのローカルプロキシに静かに移行し、開発を大幅に加速しました。 そして、日食がTomcatを蹴ってファイルの更新を開始するまで待つのは非常に面倒でした。
CSSからGSSへの移行
GSSはLESSにいくらか似ており、独自の特徴があります。
並行して、cssからgssに切り替えました。 あらゆる種類の非標準属性には多くの問題があり、原則としてcssをgssに名前変更するだけで十分です。 私がお勧めする唯一のことは、すぐにcssをアップグレードしてmixinを実装することです。 どのgssファイルが変更されたかを追跡し、gss-> cssコンパイラーを呼び出す必要があるという事実にはまだ問題がありました。
大豆の移行
SOYとは何ですか? これらは、htmlに似た構文で記述され、jsコードでコンパイルされたテンプレートです。 これにより、すべてのテンプレートの重要なクライアント側のキャッシュが解決されます。
これらすべての革新とともに、古いテンプレートをSOY(Closure Templates)に翻訳しました。 SOYは、コンパイラーが依存関係(goog.require)を配置するため、視覚部分をロジックから完全に分離し、jsコードに簡単に統合することができたため、プログラマーにとって単なるおとぎ話であることが判明しました。 SOYには名前空間があるため、Javaのように、名前空間がフォルダーの形でファイルシステムに反映されるとすぐに考えました。
大きな問題は、すべてのファイルのコンパイル時間です-Core i7 3770Kでは、すべてのgssとsoyをコンパイルするのに20秒かかります。 そのため、変更されたgssとsoyを追跡し、それらのみをコンパイルするスクリプトを作成しました-何らかの理由で、Googleはそのようなツールをパブリックドメインで提供していません。
更新:記事の執筆過程で、最適化が導入され、コンパイル時間(デバッグモード)は8〜9秒になりました。
統一
これらの問題を解決した後、私たちは最後の課題に直面しました。これら3つのテクノロジーすべてを連携させてサイトを高速化し、それがすべての目的を達成することです。
しかし、ここでいくつかのニュアンスが出てきました:cssセレクターが機能するには、 'display1'を直接呼び出すのではなく、jsのどこでもgoog.getCssName( 'display1')コンストラクトを使用する必要があります。 つまり、$ element.addClasss( 'display1')を$ element.addClasss(goog.getCssName( 'display1'))の構成に置き換える必要がありました。 さらに、変数と多数のセレクターをgoog.getCssName(...)内で使用することはできません。 つまり、goog.getCssName( 'display1 clearfix')がロールバックしないように、goog.getCssName( 'display' +値)はロールバックしません。 これは多くの不便さを引き起こしました。そのため、コンパイルスクリプトを書き直す必要がありました。そのため、すべての古いコードを「表示-」+値から通常の形式にすぐに変換できなかったため、非圧縮CSSセレクターの可能性をサポートしました。 SOY自体では、圧縮されるクラスと識別子、{css display1}などを強調表示する必要もあります。 最初の段階では、コーダーは完全に地獄でした...構文の強調表示を備えたソリューションを探していましたが、最終的には、Eclipse用のプラグインを見つけて、多くの問題を解決しました。 (http://www.normalesup.org/~simonet/soft/ow/eclipse-closure-templates.en.html)。
彼にできること:
- SOYの強調表示と構文チェック
- ネストされたテンプレートの正しい呼び出しを確認します。 欠落および追加のパラメーター
- Ctrlキーを使用したテンプレートのクイックナビゲーション
一般的に、このプラグインはコーダーにとって天国のマナになりました。 SOY-手を離すだけでなく、責任を増大させます。 少し後に、文字列を数値に変換して丸めるなど、必要なメソッドを追加するために、大豆コンパイラ用のプラグインを作成しました。 SOYの不幸は始まったばかりです。 さらに、サーバーテンプレートを新しいテンプレートエンジンに転送しました。 これを行うには、トピックと翻訳をサポートするためにクラスを再度作成する必要がありました。 古いテンプレートを新しい外観に自動的に変換するために、コンバーターを作成しました...
Googleは、SOYを異なる言語に翻訳し、別の歌を歌うことで、「すべてがそこにある」と言います。 ツールがある場合は、すべてが本当に問題ありません:)。したがって、xlfファイルまたは大豆ファイルからファイルを生成できます。 そして、ここでは、古い翻訳済みのxlfを取得して、そこに翻訳されていないものを追加することはできないことが判明しました...それは単なる悪夢です! この形式で作業するためのいくつかのひどいユーティリティセットがありますが、必要なものはありません。各フレーズにはIDがありますが、Google Closureのジェネレータクラス自体もFingerprintと呼ばれるほど高度に生成されます...この問題を解決することができました。
また、圧縮の準備が必要だったため、すべてのjsp jsページからコードを個別のモジュールに削除する必要がありました...
最後の砦
そのため、旅の始まりからさらに7か月が経過し、必要なすべてのツール、3つのテクノロジー間のすべての必要な接続がありましたが、アドバンスモードでの圧縮は機能しませんでした:)モードでは、外部を記述して接続する必要がありました。 jQueryとプラグインを理解しましたが、SOYのjs呼び出しもいくつかの非圧縮呼び出しに置き換える必要があることがわかりました。 GCはonclickで直接呼び出しを使用することを推奨していないことを理解しています。プロジェクトを0からGCに書き込む場合、これは簡単ですが、古いコードが大量にある場合はそれほど簡単ではないため、export.jsファイルを作成しました。次のような外部呼び出しのプロキシを登録しました。
global_export["showLoginDialog"] = function(event, elem) {
そのようなエクスポートされたすべての呼び出し、フォーム関数(event、this、...)の標準を設定します。つまり、最初の2つのパラメーターは必ず同じで、その後は何でもです。
エクスポートでこの問題を解決すると(呼び出し回数は20〜30回であることが判明)、GCC(Google Closure Compiler)で別の悲しい事実が明らかになりました。 GCCは、引用符「または」で「固定」されていないすべてをアドバンストモードで圧縮するため、外部プラグインへの呼び出しを修正する必要がありましたが、最大の失望は、明確に文書化されたAPI圧縮後に崩壊し、再び無期限に私たちを投げ戻しました...
ここで余談をする必要があります。Google自体はJSONオブジェクトではなく配列を渡します。 最初はProtoBufであると考えました。試してみたところ、そうではないことがわかりました。配列の各インデックスを特定のフィールドに関連付けるだけです。 どうやら、サーバーからデータが送られてくると、それらはそれをMessageFactoryに送ります。MessageFactoryはメタデータに基づいて(特定のタイプのメッセージではProtoBufメタデータが可能です)、要素をオブジェクトに接続します。 Googleのように行動すれば、もちろん、圧縮と最適化の後に問題は発生せず、配列の操作が高速になるため、速度さえ向上します)。
なぜGoogleのように振る舞わなかったのですか? 理由は、サポートする必要がある古いコードがたくさんあるからですが、これは正しい方法なので、間違いなくこのタスクを実行します。
ソリューションの検索は、GCCが「オブジェクトの古いフィールド」:「新しいフィールド名」という形式の名前変換のマップを提供できるという事実につながりました。 この機能をサポートできるようにサーバーコードをやり直し始めました。このため、5つのサービスに共通のクラスがクラスに導入されました。
外観は次のとおりです。
public interface Constants { public static final String typeId = "typeId"; public static final String user_id = "user_id"; public static final String items = "items"; .... }
ビルドする前に、GCCが生成したマップとこのクラスのルールを特別なユーティリティが使用しました。 しかし、すべてが準備ができていると思ったとき、何らかの理由でクライアント側で必要な履歴データの一部がデータベースにjsonとして保存され、人間でそれを行う方法がないことが判明しました...フィールドの名前を変更しても、データベースではすべてが非現実的です変更し、jsコードを変更するたびに新しいマップが生成されるため、変換する機会はありません。 それは完全な大失敗だった...そして、GCCは地図を提供するだけでなく、地図の変換も受け入れることができるため、反対のことをするというアイデアが浮上しました。 Constantsクラスを取得してマップに変換し、GCCに渡し、すべてのコードを圧縮しましたが、クライアントサーバーAPIに関連付けられたフィールド名には触れませんでした。 一部のフィールドに関連する奇妙なエラーを発見するまで、すべてが順調でした。 たとえば、「items」フィールドは出力ファイルの「items」のままであるはずでしたが、「items1」に名前が変更されました。 簡単な例ではすべてが時計のように機能するため、困難は依存関係を判断することが難しいことでした。 GCCソースを取得してデバッグ下で実行する必要がありましたが、引用符(または「)」<property_name>」でプロパティ名をどこかに言及すると、コンパイラはアイテムであっても変数の名前を変更します: 「GCCトラッカーにバグを作成し、コメントに単一行のパッチを追加したので、GCCを再構築し、プロジェクト全体を正常に圧縮しました。
ソースマップ
次に、圧縮され最適化された理解できないabFのヒープを理解するためにソースマップを台無しにしました(...このため、何らかの理由でGCCが最後に圧縮モジュールを追加できないため、独自のユーティリティを作成する必要がありました
、まあ、私たちは目標に向かって疲れ果てていたので、ドキュメントでこの項目を省略しました(貧弱)。
まとめ
結果として得られたもの:
非圧縮1.6 MB jsコード+ 1.4 MBテンプレート〜3.0 MB
通常の圧縮モードの38モジュールの重量はzip 445Kbで 2830 KB です
高度な圧縮モードの38モジュールzip 266KBで 1175 KB
12か月を費やしたとしても、このサイトは本当に早く動作し始めました。 同時に、私たちは仕事で課題を解決し、ゆっくりと目標に向かって動いていました...
このストーリー全体が書かれているので、これらすべての体の動きが結果に値するかどうかを想像できます。 GCライブラリでプロジェクトを開始した場合、問題は少なくなりますが、既に大量の古いコードがある場合は、このプロセスを遅らせることができます。
そして、コーダーにSOYに関するドキュメントを作成させて、彼がそこに例と標準的なソリューションを書くようにすることで、彼はより早く適応し、理解するのに役立ちます(コーダーによると:)
PS:興味のある方は、すべてのドキュメントをGoogleドキュメントに、バグをJIRAに保管しています。
ツールキット
GCLを操作するためのツールの完全なスタックを開くのはなぜですか?
まあ、オープンソース技術自体は、松葉杖ツールなしでは、誰にもanyoneめませんでした。 そして、これらの解決策が役立つ多くの素晴らしいサイトがあることを知っています。 まあ、一般的に、私はインターネットを少し良くしたいだけです:)
それでは、Closure Platformをデプロイするために何が必要ですか。 これはテストプロジェクトであり、開発を開始し、GCLの機能を示すためのベースポイントです。
OS:Linux OS、最悪の場合はOS X(BSD)。 通常のシェルが不足しているため、Windowsファミリ全体(ごめんなさい:)が横向きになります。
Java 1.6以降、ant、bash / sh、およびpython。
ほとんどのスクリプトはbashで記述され、一部はjavaで記述されています。
なぜPythonではありませんか? 私は彼が好きではないからです:)
それでは始めましょう。
クイックスタート
git clone github.com/DisDis/ClosurePlatform.git
cd ClosurePlatform
アリ
ブラウザーで起動しますWebUI / index.html
プロジェクト構造
より詳細に。
CPプロジェクトの構造:
- src-Javaソースはここに格納する必要があります。例ではConstants.javaのみ
- テーマ-gss、大豆、ロケールが保存されているテーマ。
- gss-スタイル
- 0-definitions.gss-定義
- * .gss-スタイル
- allowed.cfg-許可されたパラメーター
- allowed_prop.cfg-許可されたプロパティ
- fixed.cfg-圧縮されていない名前
- .timestampは、最後に成功したgssコンパイルの時刻を保存する一時ファイルです
- ロケール-xlf翻訳
- * .xlf-翻訳
- empty.xlf.template-空のローカライズ用のテンプレート
- テンプレート-テンプレート
- (名前空間)-テンプレートへのパス
- global.properties-グローバルテンプレート定数
- .timestampは、大豆が正常にコンパイルされた最後の時間を保存する一時ファイルです
- ツール-ツール
- WebUI-ルートとしてWebサーバーに移動するもの(Java開発者の場合、これに精通している)
- js-コード
- テーマ-コンパイルされたテーマデータ
- css
- js-コンパイルされたテンプレート
- img、data-テーマ、写真、その他すべてのデータ。
- * .html-stanichki
- build.soy.xml-これらは、ツールキットの起動を簡素化するantaのタスクです。
カスタマイズ
toolsフォルダーにはconfig.propertiesファイルがあります
なぜ必要なのか:
TIMESTAMP_FNAME=".timestamp" DEFINITION_GSS="0-definitions.gss" THEMES_PATH=$DIR/../themes THEME_LOCALES="en,ru" LOCALE_SOURCE="en" WEB_ROOT_PATH=$DIR/../WebUI WEB_THEMES_PATH=$WEB_ROOT_PATH/themes TOOL_LOCALE_PATH=$DIR/cl-templates/extractor TOOL_MERGE_PATH=$DIR/merge-xlf
$ DIRは、これらの設定を使用するスクリプトフォルダーです
DEFINITION_GSSパラメーターは、定義が配置されるgssを担当します。
THEMES_PATH-テーマフォルダーへのパス(コンパイルされたgssおよびsoyではない)
THEME_LOCALES-サポートされているローカライズのリスト
LOCALE_SOURCE-大豆で書かれたテキストはどのロケールで
WEB_THEMES_PATH-コンパイルされたgssとsoyが追加されるフォルダー
SOURCE_MAP_ROOT-ソースへのパス。必要に応じて後でnginxで簡単にラップできます。
SOURCE_MAP_FULLPATH-これは、特定の非圧縮ファイルへのフルパスです
MODULE_PATH-モジュールへのパス
他のすべてのパラメーターはそれほど重要ではありません。
Eclipseまたは別のIDE
SOYのプラグインをインストールします 。 Eclipseのプラグインを使用します 。
SOYファイルでは、ZenCondingは正常に機能します。
イベントを追加してファイルを変更し、ant soy_updateを呼び出します
ローカリゼーション
最初にローカライズを行います。
2つの方法があります。初期段階では、空のテンプレートempty.xlf.templateを使用して、適切なロケールにコピーして名前を変更することができます。 たとえば、en.xlf、ターゲット言語パラメータを目的のパラメータに変更する必要があるのはあなただけです。
ただし、テキストを大豆に翻訳する準備ができたら、create.translate.shを実行します
このツールは、すべてのトピックをスキャンし、各トピックから大豆を取得し、それらからxlfファイルを作成し、その後、古いxlfファイルとdescが一致する翻訳を取得し、一致が見つからなかった新しいファイル要素に転送しますdescによって、失われた翻訳のファイル.lost.xlfに入力されます。 それらは手作業で適切な場所に移動するか、翻訳が不要になった場合は削除する必要があります。
はい、そのような松葉杖。 より簡単な方法を提供できる場合は、このステップを喜んで簡素化します。 非常にまれなので、最適化の余地があります。
ただし、Mac OSでは、この項目は機能しません:)
GSSとSOYのコンパイル
compile.templates.shスクリプトは、変更されたgssとsoyを見つけ、これらのファイルをさらにコンパイルします。 非常に頻繁に、まあ、またはIDEを介して自動的に起動します。 スクリプトは、デバッグとリリースの2つのモードで動作します。
デバッグする
彼は何をしていますか? .timestampファイルが変更された時間に関連して変更されたファイルのすべてのトピックをスキャンし、それらをコンパイルリストに追加します。
同様のcssファイルがgssファイルごとに作成され、名前は圧縮されません。 大豆についても同様です。
リリース
リリースモードで実行するには、スクリプトの起動時にRELEASEパラメーターを指定するだけです:compile.templates.sh RELEASE
この場合、すべての(変更されたかどうかに関係なく)gssは1つのcompact.cssにコンパイルされ、すべての名前が圧縮されます。 すべてのSOYは、セレクター名を取得した個別のファイルにコンパイルされます。
定数
既に述べたように、オブジェクトの一部のプロパティを圧縮できない場合があります。たとえば、クライアントとサーバーの相互作用です。 あなたはグーグルのように振る舞うことができますが、私は他の誰かがグーグルのように振る舞うという決定を見たことはありません。
サンプルプロジェクトでは、src / com / example / utils / Constants.javaから取得したjavaファイルから非圧縮プロパティのマップを生成します
このスクリプトは、constantsToMap.shの生成を担当します。このファイルは、Constants.javaファイルを取得し、そのファイルにproperty.in.mapファイルを作成します。
定数の名前がコンテンツと一致することを確認しながら(items = "items")。
property.in.mapは、
< >:< >
私たちの場合、古い値と新しい値は同じです。 標準の配信では、GCCは定数を誤って処理します;トラッカーとパッチにバグがあります。
テストプロジェクトにはGCCのパッチが適用されたバージョンがあります。パッチがいつメインブランチで受け入れられるかはわかりませんが、コミュニティはそれをスピードアップできます;)
このファイルはどこからでも生成できます。Javaのソリューションが提供されている例の場合、データ形式は簡単です。
エクスターン
jQueryや圧縮されないプラグインなどの外部コードとやり取りするには、「モジュールアセンブリ」セクションで接続するExternを登録する必要があります。
すべてのexternファイルはtools / cl-externsフォルダーに保存されます
この例では、プロジェクト用のツール/cl-externs/example.jsがあります。詳細はオフィスで確認できます。 GCCドキュメント 。
モジュールの組み立て
tools / gcmoduleフォルダーとgcmodule.jarアプリケーションがこれを担当し、ant soy.create.modulesを実行する方が簡単です
開始する前に、すべてのgssと大豆をリリースモードで収集する必要があります。 これは、ant soy.compile-RELEASEを使用して実行できます。
タスクを簡素化し、これら2つのアクションを単一のコマンドにするには
ant check.modules
複数のファイルまたはフォルダーを組み合わせてモジュールにすることができます。 モジュールは他のモジュールなどに依存する場合があります。 サイトの共通部分を個別のモジュールで選択し、すべてのページに個別のモジュールを作成することをお勧めします。 なぜそれを行う必要があるのかを以下に説明します。
モジュールを構成するためのconfig.cfgファイルがあります
なぜこれがスクリプトではないのか、最初はbashで書きたかったのですが、配列のソートのために非常に難しいことがわかりました。
プログラムの本質-config.cfgからフォルダーとファイルのリストを取得し、Googleツールを使用して依存関係ツリーを生成し、モジュールごとに並べ替えてからコンパイラーに渡します。 これは、通常の圧縮モードで行われます。アドバンストモードでは、コンパイラー自体が依存関係を構築できますが、GCLですぐに開始しないプロジェクトの場合、これは非現実的です。 したがって、プロジェクトの移行フェーズでは、通常の圧縮を使用します。そこで、ファイルを目的の順序で明確にフィードする必要があります。 通常の圧縮モードに切り替える方法については、以下で説明します。
ここで注意すべきことが1つあります。1回の実行で1つのトピックに対して1つのロケールしか生成できませんが、残念ながら克服するのは簡単ではありません。 ただし、さまざまなパラメーターで実行して、この問題を解決できます。
そのため、テストプロジェクトでは、WebUI / js / module / ru / *フォルダー内のモジュールのアセンブリを開始した後、各ファイルのモジュールと生成および処理された(antを実行する場合)ソースマップが散在します。
出力にはproperty.out.mapファイルも含まれます。これは、フィールド名の変更のマップを含むファイルです。
< >:< >
config.cfg
したがって、構成ファイルは通常のJSONオブジェクトです。
{ options:<>, modules:[<>] }
設定は何ですか:
{ defines:{ "LANG":"ru", "THEME":"default", "OPTIMIZATIONS": "ADVANCED_OPTIMIZATIONS" }, deps:{ params:" -o list", workPath:"../../tools/closure/bin", exec:"python ./calcdeps.py" }, compiler:{ params:" <anchor>habracut</anchor> ", workPath:"../../tools/closure/", exec:"java -jar compiler.jar" }, moduleManager:{ path:"../../WebUI/js/module/%THEME%/%LANG%/", tree:"moduleinfo.js" }, exclude:[ "/.svn/", "/closure/base.js" ], workPath:"../../WebUI/js" }
モジュール
{ name:< >, required:[< >], files:[< >], path:[< , %THEME%, %LANG%"], exclude:[< >] }
コマンドラインから定義を上書きできます:
java -jar gcmodule -D<key>=<value> -D<key2>=<value2> -C"<Config file>"
構成ファイルは省略できます。
例:
java -jar gcmodule -DLANG=en -DTHEME=other
ソースマップ
ant soy.create.modulesを使用してモジュールのアセンブリを開始した場合、圧縮ファイルのマップの処理が自動的に開始されました。
parseMap.shスクリプトがこれを担当します
彼は、フォルダー内で見つかったすべてのモジュールを取得し、マップファイル内のパスを構成で指定されたURLに変更します。 なぜURLですか? nginxを使用して簡単にオーバーロードできるため、アプリケーションを簡単にデバッグできるためです。
Nginx設定
ソースがローカルにあるか、ソースがリモートサーバー(192.168.1.88)にあるかによって2つのオプションがあり、必要なものを選択します。
/ etc / nginx / sites-available / sourcemap.cp.com
#------------------------------- server { listen 80; server_name sourcemap.cp.com; proxy_buffering off; expires 0m; # Local map root /home/dis/workspace/CP/; # Remote map to source.cp.com #location / { # proxy_set_header Host "source.cp.com"; # proxy_pass "http://192.168.1.88:80"; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #} } #-------------------------------
sudo ln -s /etc/nginx/sites-available/sourcemap.cp.com /etc/nginx/sites-enabled/sourcemap.cp.com
hosts / etc / hosts
127.0.0.1 sourcemap.cp.com
再起動
sudo service nginx restart
たとえばページ
例では、ページの2つのオプション-通常とリリース。
通常のページはデバッグに使用され、最も重要なセクションはcssとスクリプトに関連しています。
<link rel="stylesheet" href="themes/default/css/0-reset.css" type="text/css" media="screen" title="no title"> <link rel="stylesheet" href="themes/default/css/1-main.css" type="text/css" media="screen" title="no title"> <script type="text/javascript" charset="utf-8"> Handlers={}; Handlers.rootPath="/"; </script> <script type="text/javascript" src="themes/default/js/renaming_map.js"></script> <script type="text/javascript" src="js/jquery/core/1.8.1/dev/jquery.js"></script> <script type="text/javascript" src="js/third_party/moment/moment.js"></script> <script type="text/javascript" src="js/closure/goog/base.js"></script> <script type="text/javascript" charset="utf-8"> goog.require('example.page.index'); </script>
ここでは、すべてのcssを手作業で処方する必要があるという事実のみに注意を払う必要があります。
リリースバージョンの方が簡単です。
<link rel="stylesheet" href="themes/default/css/compact.css" type="text/css" media="screen" title="compact"> <script type="text/javascript" charset="utf-8"> Handlers={}; Handlers.rootPath="/"; </script> <script type="text/javascript" src="js/jquery/core/1.8.1/jquery.js"></script> <script type="text/javascript" src="js/third_party/moment/moment.js"></script> <script type="text/javascript" src="js/module/default/ru/closure.js"></script> <script type="text/javascript" src="js/module/default/ru/template_theme.js"></script> <script type="text/javascript" src="js/module/default/ru/game.js"></script> <script type="text/javascript" src="js/module/default/ru/p_index.js"></script>
必要な順序でモジュールのみを指定する必要があります。
まとめ
Javaでテーマとロケールをサポートするためのバインディングはありませんが、高速でコンパクトなアプリケーションを作成するための出発点があります。 GCLドキュメント。 確かに非常に強力なテクノロジーであるため、これらのツールがGCLの使用をスピードアップするのに役立つことを願っています。 Googleが私のためにツールをオープンソースでリリースしないのは謎のままです。 GPLv3スクリプトのライセンス。
PS github.comのバグとパッチが嬉しい
GCCとgmoduleのプラグインは、少し後に開かれます。
の。 GCCドキュメント