「マイクロローダー」は Sencha の JavaScript および CSS に対応したデータ駆動型ローダーです。マイクロローダーは Sencha Cmd で生成アプリケーションの一部として提供されます。本ガイドでは、マイクロローダーの機能を理解し、特定の要件に合わせて調整する方法を説明します。
Sencha Touch が使用するマイクロローダーは現時点では Ext JS が使用するマイクロローダーとは実装が異なる点を明確にすることが重要です。Sencha Touch の実装は Ext JS では現時点でサポートされていない追加機能を提供します。いずれも Sencha Cmd で提供され、すべての機能を両方のフレームワークで利用可能にする予定です。
マニフェスト
app.json
このファイルでアプリケーションの詳細を指定します。この設定ファイルは Sencha Cmd ビルドプロセスによって最初に使用されます。Sencha Cmd は app.json
のコンテンツを変換し、出力されるマニフェストを実行時に使用するためにマイクロローダーに渡します。最後に、Ext JS も設定オプションがあるか実行時マニフェストに問い合わせます。
Ext.manifest
アプリケーションを起動すると、“Ext.manifest” としてロードされた app.json
の処理済みのコンテンツが表示されます。Ext JS 5 は互換レイヤーの有効化などを行うために指定した Ext.manifest プロパティを使用します。このオブジェクトをロードするためにマイクロローダーがサポートするオプションは多数ありますが、これについては後述します。
スクリプトタグ
マイクロローダーを使用するには、次のスクリプトタグを含める必要があります。
<script id="microloader" type="text/javascript" src="bootstrap.js"></script>
デフォルトでは、このスクリプトはビルドプロセスで置換されますが、開発中はアプリケーションのロードに使用されます。
デフォルトとカスタマイズ
Sencha Cmd が生成する app.json
には調整できる多くのプロパティが含まれています。これらのプロパティはそれぞれ何をコントロールするかについてインラインで説明があります。
プロジェクトをアップグレードする場合、app.json
には可能なオプションがすべて含まれていないことがあります。アップグレードを行うと、見つからないプロパティのデフォルト値が “.sencha/app/app.defaults.json” で見つかることがあります。
最も関心の高いプロパティを以下に示します。
indexHtmlPath
これはアプリケーションの HTML ドキュメント(app.json
ファイルと比較して)へのパスです。デフォルトでは、このプロパティは “index.html” に設定されています。サーバーが PHP、ASP、JSP その他の技術を使用している場合、この値を適切なファイルをポイントするように変更できます。
"indexHtmlPath": "../page.jsp"
この設定を変更すると、おそらく “output” オプションも変更する必要があります(以下参照)。
theme
Ext JS アプリケーションの場合、これはテーマパッケージの名前です。例:
"theme": "ext-theme-crisp"
framework
フレームワークの名前です。“ext” または “touch” です。例:
"framework": "ext"
js
ロードする JavaScript コードファイルの説明の配列です。デフォルトでは、Ext JS 5 アプリケーションには次のようなものが含まれます。
"js": [{
"path": "app.js",
"bundle": true
}]
このエントリはアプリケーションのエントリポイントを指定します。“bundle” フラグは、“sencha app build” を実行する場合にこのエントリをビルドの連結された出力で置換する必要があることを示します。このように他のファイルをこの配列に追加できます。
"js": [{
"path": "library.js",
"includeInBundle": true
},{
"path": "app.js",
"bundle": true
}]
ファイルを追加する場合、ビルドプロセスの処理を示すオプションのプロパティがあります。例えば、上記の場合、“library.js” が連結されたビルド出力に含まれ、実行時マニフェストから削除されます。
その代わりに “includeInBundle” を削除した場合、“library.js” はアプリのフォルダに存在すると想定され、ビルド出力フォルダにコピーされます。エントリはマニフェストに残り、マイクロローダーに個別にロードされます。
マイクロローダーがロードして(ビルドプロセスにコピーしないように)エントリを渡すには、次のように “remote” プロパティを追加します。
"js": [{
"path": "library.js",
"remote": true
},{
"path": "app.js",
"bundle": true
}]
この配列にエントリを追加できますが、ほとんどの依存関係はコードの “requires” 文または(パッケージを必要とする)app.json
に表示されます。
注意:Sencha Touch では、“sencha-touch-debug.js” が通常 “js” 配列に含まれます。“framework” 設定で十分なので、このエントリは Ext JS 5 では必要ありません。
css
CSS 資産は JavaScript とは処理が若干異なります。これはストック Sencha Cmd アプリケーションで CSS が Sass ソースからコンパイルされるためです。“css” プロパティの初期コンテンツは次のようになります。
"css": [{
"path": "boostrap.css",
"bootstrap": true
}],
この CSS ファイルは Sass スタイル設定のビルドをインポートするシンプルなスタブです。“bootstrap” フラグはエントリが開発に使用されますが、ビルド出力から削除する必要があることを示します。ビルドに対して、Sass からコンパイルされたCSS ファイルが生成されたマニフェストの “css” 配列に付加されます。
まず、“bootstrap.css” は以下のようにテーマをフレームワークからインポートします。
@import "..../ext-theme-neptune/build/ext-theme-neptune-all.css";
アプリをビルドすると、ビルドされた最新の CSS ファイルをポイントするようにこのファイルが更新されます。例えば、“sencha app build” を実行すると、本番環境の CSS ファイルが次のように “bootstrap.css” によってインポートされます。
@import "..../build/..../app-all.css";
“css” エントリも “remote” プロパティをサポートします。リモートが設定されていない場合、ビルド出力フォルダにコピーされるように “js” エントリで動作します。
requires
この配列は必要なパッケージの名前を保持します。Sencha Cmd がこのリストを処理する場合、見つからないパッケージをワークスペースに自動的にダウンロードして抽出します。同様に、パッケージの package.json に “requires” が含まれます。これらは必要に応じてダウンロードされ抽出されます。
これらのパッケージ名にはバージョン要件も含まれます。バージョン番号の指定についての詳細は、Sencha Cmd パッケージを参照してください。
output
“output” オブジェクト(Sencha Cmd 5.0.1 で追加)を使用すると、ビルド出力の生成場所と方法をコントロールできます。このオブジェクトはビルド出力の多くの要素をコントロールできます。上記では “indexHtmlPath” を使用し、Sencha Cmd にページのソースが “../page.jsp” であると伝えました。このプロセスを完了するために、“output” を使用して Sencha Cmd にビルドされたページがビルドされた JavaScript と CSS に相対する形で存在する場所を伝えます。ソースツリーと同じ相対的な配置を維持するには、これを app.json
に追加します。
"output": {
"page": {
"path": "../page.jsp",
"enable": false
},
"manifest": {
"name": "bootstrap.js"
}
}
この場合、さらに “enable” を追加して false に設定しました。この組み合わせは Sencha Cmd に最終ページの場所を伝え、(“indexHtmlPage” で指定しているように)ソースをコピーして生成しないように指示します。
ページは生成しないので、マイクロローダースクリプトタグには同じ “bootstrap.js” の “src” 値が含まれます。上記の “manifest” オプションは、同じ名前で Sencha Cmd にビルドされたマイクロローダーを生成するように指示します。これは、JSP や ASP などのサーバーサイドテンプレート環境に共通するニーズです。
その他
これまでに見てきたプロパティの多くはビルドプロセスへの指示でしたが、それ以外にもマイクロローダーによって処理されるものもあります。上述の通り、マニフェストは Ext JS によって機能の設定方法としても解釈されます。これらのプロパティやその他プロパティに関する詳細は、app.json
のコメントを参照してください。
ビルドプロファイル
アプリケーションにバリエーションがある場合、このように(Kitchen Sink から取得して)“builds” オブジェクトを app.json
に追加して目的のビルドを記述できます。
"builds": {
"classic": {
"theme": "ext-theme-classic"
},
"gray": {
"theme": "ext-theme-gray"
},
"access": {
"theme": "ext-theme-access"
},
"crisp": {
"theme": "ext-theme-crisp"
},
"neptune": {
"theme": "ext-theme-neptune"
},
"neptune-touch": {
"theme": "ext-theme-neptune-touch"
}
}
“builds” のそれぞれのキーは “build profile” と呼ばれます。この値は、出力マニフェストを以下に示すように 出力マニフェストとして作成するための app.json
のベースコンテンツに適用される一連のプロパティオーバーライドです。この場合、“theme” プロパティだけが各ビルドプロファイルに対して変更されます。
さらに、アプリケーションビルドの共通のバリエーションであるオプションの次の 2 つプロパティがあります。“locales” と “themes”です。これらは最終ビルドプロファイルを作成するプロセスを自動化するために使用されます。例えば、Kitchen Sink は “locales” を使用します。
"locales": [
"en",
"he"
],
“locales” または “themes” が与えられている場合、それぞれの値が “builds” のそれぞれのエントリと組み合わせられて最終マニフェストを作成します。この場合、“neptune-en”、“neptune-he”、“crisp-en”などが最終ビルドプロファイル名です。
マニフェストの生成
前述の通り、app.json
はビルドプロセス中に変換されてから、実行時に “Ext.manifest” として提示されます。このプロセスは Ext.merge のようにオブジェクトのマージで構成されますが、2つの配列が「マージ」されると連結される点に注意が必要です。
この変換の最初の手順は目的のビルド「環境」(“production” または “testing” など)の設定のマージです。この後に、ビルドプロファイルが使用されている場合に、そのコンテンツがマージされます。最後に、パッケージ化ツール(“cordova” または “phonegap”)が設定されていると、そのプロパティがマージされます。
疑似コードでは、これは次のようになります。
var manifest = load('app.json');
// These would come from the "sencha app build" command:
var environment = 'production';
var buildProfile = 'native';
mergeConcat(manifest, manifest[environment]);
if (buildProfile) {
mergeConcat(manifest, manifest.builds[buildProfile]);
}
if (manifest.packager) {
mergeConcat(manifest, manifest[manifest.packager]);
}
パッケージ
マニフェスト作成の最後の手順は必要なパッケージの追加です。
必要なパッケージが “js” または “css” エントリをその package.json で指定する場合、これらはパッケージ依存関係の順序ですでに作成されている配列の前面に連結されます。これによって、パッケージがこのような依存関係自体を処理できます。
“js” エントリと “css” エントリに加えて、必要な各パッケージの package.json ファイルのコンテンツが若干クリーンアップされ、パッケージをキーとする最終マニフェストの “packages” オブジェクトに追加されます。app.json
がすでに “packages” オブジェクトを含む場合、そのオブジェクトは対応する package.json ファイルのコンテンツとマージされます。プロパティを設定オプションとしてパッケージに渡せるように app.json
が優先されます(以下参照)。
疑似コードでは、app.json
と package.json のコンテンツが次のようにマージされます。
var manifest; // from above
manifest.packages = manifest.packages || {};
var js = [], css = [];
// Expand required packages and sort in dependency order
expandAndSort(manifest.requires).forEach(function (name) {
var pkg = load('packages/' + name + '/package.json');
js = js.concat(pkg.js);
css = css.concat(pkg.css);
manifest.packages[name] = merge(pkg, manifest.packages[name]);
});
manifest.css.splice(0, 0, css);
var k = isExtJS ? 0 : manifest.js.indexOf('sencha-touch??.js');
manifest.js.splice(k, 0, js);
これによって、次のような Ext.manifest が作成されます。
{
"name": "MyApp",
"packages": {
"ext": {
"type": "framework",
"version": "5.0.1.1255"
},
"ext-theme-neptune": {
"type": "theme",
"version": "5.0.1.1255"
},
...
},
"theme": "ext-theme-neptune",
"js": [{
"path": "app.js"
}],
"css": [{
"path": "app.css"
}],
}
このマージの結果は、パッケージ “foo” が package.json(“bar” など)でグローバルオプションを提供し、デフォルト値を設定できることを意味します。foo パッケージを使用するアプリケーションはいずれも app.json
でこのオプションを次のように設定できます。
"packages": {
"foo": {
"bar": 42
}
}
パッケージはこの値を次のように取得します。
console.log('bar: ' + Ext.manifest.packages.foo.bar);
ロードの順序
開発でアプリケーションをロードする場合とビルドの大きな違いの 1 つは、個別のファイルをブラウザに表示する順序です。前のリリースでは、app.js ファイルがブラウザによって処理される最初のファイルにかなり近くなっていました。要件が示されたので、より多くのファイルがロードされそれらの要件が明らかになるなどです。
ただし、ビルドではこの順序は逆になります。app.js ファイルはほとんど常にビルド出力の最後のファイルです。これはコードが開発では機能するものの本番環境で失敗するような状況が容易に発生し、望ましい状況ではありません。
Ext JS 5 では、ビルドに使用されるロードの順序がマニフェストに追加され、同じ順序でファイルをロードするために使用されます。これによってマニフェストは相当大きくなりますが、使用されるのは開発中のみです。
マニフェストのロード
マイクロローダーは app.json
に記述され、Ext.manifest で渡されている通りにアプリケーションをロードします。このために、マイクロローダーは最初にマニフェストをロードする必要があります。これを行うための 3 つの基本的な方法を以下に示します。
埋め込みマニフェスト
通常のアプリケーションでは、選択するテーマ、ロケール、フレームワークは 1 つだけなので、マニフェストは 1 つだけになります。このマニフェストはダウンロード時間を最適化するために出力マークアップファイルに配置できます。
このオプションを有効にするためには、以下を app.json
に追加します。
"output": {
"manifest": {
"embed": true
}
}
この設定はマニフェストとマイクロローダーをマークアップファイルに埋め込みます。
名前付きマニフェスト
ビルドプロファイルを使用する場合、マニフェストを埋め込むことはできません。その代わりに、名前が与えられていればロード時にマイクロローダーがマニフェストをリクエストできます。デフォルトでは、生成される app.json
ファイルはマークアップファイルと同じフォルダに配置され、これはデフォルトのマニフェスト名です。別の名前を指定するには、次を行います。
<script type="text/javascript">
var Ext = Ext || {};
Ext.manifest = 'foo'; // loads "./foo.json" relative to your page
</script>
このアプローチは、名前をハードコーディングではなく生成することによって、サーバーサイドでビルドプロファイルを管理するための便利な方法です。
動的マニフェスト
ビルドプロファイルのクライアントサイドを選択したい場合もあります。これをシンプルにするために、マイクロローダーは “Ext.beforeLoad” と呼ばれる hook メソッドを定義します。次のようにこのメソッドを定義すると、プラットフォームの検知を利用しながらマイクロローダーで処理する前に “Ext.manifest” の名前またはコンテンツをコントロールできます。
<script type="text/javascript">
var Ext = Ext || {};
Ext.beforeLoad = function (tags) {
var theme = location.href.match(/theme=([\w-]+)/),
locale = location.href.match(/locale=([\w-]+)/);
theme = (theme && theme[1]) || 'crisp';
locale = (locale && locale[1]) || 'en';
Ext.manifest = theme + "-" + locale;
};
</script>
上記は Ext JS 5 Kitchen Sink の例から取得しています。この例ではいくつかのテーマと 2 つのロケール(英語「en」とヘブライ語「he」)でビルドしています。このメソッドを提供することで、ビルドプロファイル名が “crisp-en” などの値に変更されます。これは app.json
ではなく “crisp-en.json” マニフェストをロードするように指示します。
ビルドプロファイルの選択プロセスはアプリケーションで必要とされるもので構いません。サーバーサイドのフレームワークはページの描画に合わせてこの選択を行う可能性があります。これは Cookie や、その他の個人データをベースにしている場合があります。上記の場合、純粋に URL をベースにしています。
プラットフォームの検出 / 応答性
多くの場合に、デバイスまたはブラウザが主な選択基準になるので、マイクロローダーは “tags” と呼ばれるオブジェクトを beforeLoad に渡します。このオブジェクトは、検知した様々なプラットフォームタグをプロパティとして含みます。すべてのタグを次に示します。
- phone
- tablet
- desktop
- touch
- ios
- android
- blackberry
- safari
- chrome
- ie10
- windows
- tizen
- firefox
これらのタグを使用する場合または変更する場合でも、beforeLoad メソッドを使用できます。さらに、このオブジェクトを使用して資産(マニフェストに記述された js または css アイテム)および platformConfig によって設定された実行時コンフィグ値のフィルタリングをコントロールします。このフックによって、これらのフィルタが一致するアイテムをコントロールできます。ただし、これらのタグの変更はアプリケーションで意味のある新しいタグの追加が主な目的です。カスタムタグはプレフィックス “ux-” を付ける必要があります。Sencha が提供するタグはこのプレフィックスでは始まりません。