HOME > 開発者向けBLOG > Sencha Blog >  Sencha Cmdパッケージを理解する

Technology Note 開発者向けBLOG

Sencha Blog

Sencha Cmdパッケージを理解する

こんにちは、ゼノフィnakamuraです。

この記事は、US Sencha社ブログ Understanding Sencha Cmd Packages を翻訳したものです。

cmd-teaser今年の4月に、 Ext JS 4.2と新しいNeptuneテーマを公開し、それと同時にSencha Cmd 3.1にパッケージのサポートを導入しました。当時、パッケージは主にテーマをターゲットにしていましたが、内蔵しているJavaScript、Sassとリソースのユースケースは明らかにテーマだけではありません。この記事でパッケージの内幕を検討していき、最も利用されるだろうユースケースに活かす方法を示します。その方法とは、アプリケーションの間でコードを共有することです。

ステージを設定する

Sencha Cmdでは、各アプリケーションはワークスペースに存在しています。ワークスペースは、自分で選択するルートフォルダで、アプリケーション、パッケージ、Senchaフレームワークなどが存在する場所です。ワークスペースとして、ソースコントロールにルートフォルダを設定するのは通常ですが、これは必要ではありません。この記事では、空のフォルダにテストワークスペースを生成します:

C:\Test> md wksp
C:\Test> cd wksp
C:\Test\wksp> sencha generate workspace .
Sencha Cmd v4.0.1.45
...

初めに、このワークスペースで二つのExt JSアプリケーションを設定しましょう。デフォルトの設定によって、「sencha generate app」を実行すると、アプリケーションとともにワークスペースを取得するので、その二つは同じフォルダに入っています。そのワークスペースは、既存のワークスペースでアプリケーションを生成しないかぎり、たった今生成したワークスペースになります。

次のコマンドは、Ext JS 4.2.1をダウンロードして、そのzipファイルを解凍した場所をSencha Cmdで指定しています。最初にワークスペースで生成されるExt JSアプリケーションは、必要なExt JS SDKのサブセット(または「フレームワーク」)を「ext」フォルダにコピーします。次に生成されるアプリケーションはワークスペース内の既存のフレームワークを共有するため、この操作は不要になります。

C:\Test\wksp> sencha -sdk ../ext421 generate app ExtApp1 extApps/app1
Sencha Cmd v4.0.1.45
...
[INF] Workspace does not have framework ext at C:\Test\wksp ... copying
...
C:\Test\wksp> sencha -sdk ext generate app ExtApp2 extApps/app2
Sencha Cmd v4.0.1.45
...

現時点ではワークスペース、Ext JSのサブセット、空のアプリケーションを2つ持っており、フォルダ構成は次のようになっています:

wksp/
    ext/             (A copy of the necessary files for Ext JS)
        packages/    (Packages provided by Ext JS)
    extApps/
        app1/
        app2/
    packages/        (A folder for non-framework packages)

パッケージを作りましょう

パッケージは次のような、アプリケーションと似た構文で生成することが可能です:

C:\Test\wksp> sencha generate package common
Sencha Cmd v4.0.1.45
...

ここの主な違いは、新しいパッケージが「packages」のフォルダに入ることです:

wksp/
    ...
    packages/
        common/
            resources/
            sass/
            src/
            package.json
            ...

我々のアプリケーションでこのパッケージを利用するには、それぞれの「app.json」ファイルの「requires」配列にこれを追加します:

1
2
3
"requires": [
    "common"
]

その結果は?

その最も明白な結果は、このアプリケーションのビルドに、「common」パッケージのJavaScriptペイロードが組み込まれることです。それは「classpath」のレベルで行われます。Sencha Cmdで各アプリケーション(とパッケージ)は独自のクラスパスがあります。デフォルトで両方のアプリケーションの「.sencha/app/sencha.cfg」ファイルにこの設定があります:

1
app.classpath=${app.dir}/app

そして、パッケージは「.sencha/package/sencha.cfg」にこの設定があります

1
package.classpath=${package.dir}/src

「app.json」の「requires」のお陰で、それぞれのパッケージを要求するための「package.classpath」が(「app.classpath」とともに)コンパイラの内部(合計)クラスパスに追加されます。このパスに位置する全てのJavaScriptファイルはコンパイラでスキャンされ、使用可能になります。

これらの設定がアプリケーションで利用されることを合理化する為に、コンパイラが取得する情報は「bootstrap」というものにエクスポートされます。もし既に「Ext.Loader.setConfig」または「Ext.Loader.setPath」のAPIをよく御存知でしたら、これは必要ではありません!その代わり、必要な(もしくは必要以上の)パスが各アプリケーションの「bootstrap.js」ファイルにあるでしょう。

これはパッケージの依存関係ができる全てではありません。しかし、パッケージの利用を始めるためには充分です。

パッケージの利用

次は何でしょう?通常の(間違った)推定は、パッケージがアプリケーションに対して有用になる前に、「sencha package build」を利用して最初の構築を行わなければならないということです。しかし実際には、Sencha Cmdがパッケージを利用するために知る必要があることは、パッケージのクラスパスだけなのです。

質問の正しい答えは「アプリケーションのbootstrapを”refresh”する必要がある。」になります。もし(Cmd v4に新しい)「sencha app watch」のコマンドを利用していたら、watchを再び立ち上げることで必要な手順は全て行われるでしょう。パッケージの依存関係を追加することを、今のところ「sencha app watch」は内部的に処理することはありませんので、現在は手動による再起動が必要です。しかし、このパッケージに新しいパッケージが追加される度に、watchアプリケーションはこれを検出して、自動的にブートストラップをリフレッシュします。

Sencha Cmdはほとんどの機能にはJava 6が必要ですが、「sencha app watch」はJava 7に依存しています。このことに問題がありましたら、Cmd v4以前から使用可能だったコマンド(sencha app refresh)を利用できます。このコマンドは特定の場合に必要なことだけを正確に行います。Cmd v4では、これはアプリケーション構築の「refresh」ターゲットを実行させる便利な方法です。言い換えると、「sencha app build」はブートストラップもリフレッシュしますし、Sassと他のものもいくつか作成します。

「sencha package build」は何をしますか?

パッケージが生成される構築スクリプト(「sencha package build」の実装)は二つのユースケースを管理します。1)(「ext-all.js」ファイルに似ている)Cmdではないアプリケーションのパッケージソースのビルドを生成することと2)配布のためにパッケージを用意することです。共にCmdに基づいたアプリケーションでワークスペース内のローカルパッケージには必要ありませんので、パッケージ構築を完全に無視してもこのシナリオには問題ありません。

このテーマはガイドで説明されていますので、詳しくはそちらをご覧ください。

コンポーネント、またはビューを持つパッケージ

ワークスペースには、二つの(ほぼ)空のアプリケーション、Ext JS SDK、「common」という名前のパッケージがあります。アプリケーションはcommonパッケージに追加されたコードが利用できますが、例えば、カスタムコンポーネントやMVCアプリケーションのビューの様な複雑なものを共有したい時に面白いことになります。2つの「別」な内容の種類の物から来る複雑さは、それらを共有するために必要になります。スタイルとリソース(例:イメージ)です。

Sassの共有

パッケージはテーマの要件を解決するために元々設計された上で提供され、Sass(Senchaフレームワークが利用する「CSS++」の方言)のソースコードを含めることが出来ることは当然で、Sencha Cmdはこのコードをアプリケーションのビルドに含める方法を知っています。

パッケージの前は、Sassソースファイルとそれぞれに対応するコンポーネントの間の関係を知るための明らかな方法はありませんでした。このため、以前はアプリケーションのJavaScriptコードの現在の状態に基づいて、手動で必要なすべてのscssファイルの包含を制御することになっていました。

しかし、パッケージでは、Sencha CmdがJavaScriptクラスをそれぞれの関連しているSassコードに連携するための仕組みを提供しています。これはクラス名の通信で行います。例えば、テーマによって「Ext.button.Button」のクラスは「button/Button.scss」ファイルと関連しているなどです。

これらのクラスのJavaScriptコードを整理するのに、おすすめの方法になっていますので、もちろん他のソースファイルもこのように整理されます。この関連のお陰で、生成されたCSSファイルはアプリケーションで実際に利用されるコンポーネントのスタイルだけを含めて、予想できるようにベースクラスから派生クラスに重ねて表示します。

テーマガイドの中に、この文書に関係している内容はたくさんあります。このパッケージの一部はまだSencha Touchアプリケーションに現在反影しておりません。

リソースの共有

複数のパッケージからアプリケーションを作成することに対して、興味深い課題はそれぞれのリソースをどう独立させるかということです。二つのアプリケーションが書かれた時には、2つはお互いの存在はおそらく知りませんが、両方を利用したいアプリケーション内ではどうにかして共存しないといけません。JavaScriptでは名前空間によって行いますが、イメージはどうしましょう?

Ext JSテーマでは、theme-background-imageのファイル名を提供されたSass関数がありますので、これでイメージパスを解決します。この関数はコンフィグプロパティによって、正確なプレフィックスとファイルタイプのサフィックス(.gifまたは.png)まで反影させます。それは次のように利用されます:

1
2
3
.foo {
    background-image: theme-background-image('foo');
}

テーマの場合は、テーマの継承階層の中のパッケージの「resources」フォルダは、それぞれの上で同じ階層化されます。このため、派生テーマがベーステーマからイメージ資産を選択的に上書きできます。このリソースは全て作成されたアプリケーションの「resources」フォルダにコピーされます。通常は「resources/images」にコピーされます。それは:

build/
    resources/
        app-all.css
        images/
            foo.gif

Sassは「resources」フォルダ内でCSSファイルを生成するためにコンパイルされます。このため、このテーマイメージに生成された相対パスは最適に短くなります。:「images/foo.gif」。これが、Cmdがダウンロードサイズを小さくするもう一つの方法になります。

この同じのメソッドはテーマの無いパッケージにもききます。ただ一つの違いは、このようなパッケージの「resources」フォルダはパッケージで名付けられたアプリケーションの「build/resources」フォルダのサブサブフォルダにコピーされます:

build/
    resources/
        app-all.css
        images/
            foo.gif
        common/
            images/
                foo.gif

テーマの無いイメージのイメージパスは少し長くなります: “common/images/foo.gif”.

これらを全てSencha App Watchが管理するの?

はい。「sass」と「resources」フォルダでファイルが変更されたら、そのファイルが自動的にピックアップされます。Sassファイルの変化は増分のCompass構築を発生させます。同じくリソースフォルダの変更はbuild/resourcesフォルダに同期されます。ファイルシステムが落ち着いた何秒後に、ブラウザにリロードされる状態になっているはずです。

実際に動いているパッケージ

ここまでの内容と他が実際に利用されている例を次のGithubリポジトリで示しています:

  • このリポジトリは見本のテーマパッケージとカスタムボタンコンポーネントパッケージがあります。
  • このリポジトリはベースの色を利用するカスタムボタンコンポーネントがありますし、独自のSass mixinとmixinから作成された二つの異なるUIを表示する見本のアプリケーションを提供しています。
  • このリポジトリはパッケージを利用してSencha TouchとExt JSの異なる組み合わせの間でコードを共有しているワークスペースが二つ含まれています。

パッケージに対する一般的な情報はPackagesガイドをご覧下さい。

PAGETOP