8 Oracle JET Webコンポーネントの使用

Oracle JET Webコンポーネントは、カスタムHTML要素として埋め込むことができる、再利用可能なユーザー・インタフェース・コードの単位です。Webコンポーネントには、Oracle JETコンポーネント、他のWebコンポーネント、HTML、JavaScriptおよびCSSが含まれます。独自のWebコンポーネントを作成するか、ページに追加できます。

カスタムWebコンポーネントの設計

Oracle JET Webコンポーネントは、複数のコンポーネント・タイプを含むカスタム・コンポーネントです。作成するWebコンポーネントは、アプリケーションで使用することも、Oracle Component Exchangeにアップロードして他の開発者と共有することもできます。

Oracle JETとOracle Component Exchangeでサポートされる様々なコンポーネント・タイプは次のとおりです。

  • スタンドアロンWebコンポーネントは、なんらかのUIと定義された一連のプロパティ、メソッド、イベント、スロットを含む従来のUIコンポーネントです。これは、単純で良いボタン・タイプのウィジェットから、カレンダのようにきわめて複雑なページ全面のコンポーネントまで、あらゆるものを表すことができます。
  • パック・コンポーネント(JETパック)は、一緒に使用されることを目的とした関連するコンポーネントのバージョン・ストライプを表します。コンシューマがJETパックのメンバーであるコンポーネントを選択すると、コンシューマのアプリケーションは、パック内の個々のコンポーネントではなくパック全体のバージョンと関連付けられます。JETパックによって、そのようなプロジェクトの設定と依存関係の管理が全体的に単純化されます。
  • リソース・コンポーネントは、JETパックに含まれるWebコンポーネントによって使用されるアセットの再利用可能ライブラリです。リソース・コンポーネントには、通常、共有イメージ、リソース・バンドル、ユーティリティ・クラスなどが含まれます。リソース・コンポーネントには厳密に事前定義された構造がないため、必要であればなんでも含めることができます。ただし、これによってUIコンポーネントは提供されません。そのかわり、従来のスタンドアロン・コンポーネントが、共有リソースのためにこれらのいずれかを利用します。リソース・コンポーネントはJETパックと連携した使用のみを想定しています。
  • 参照コンポーネントは、サードパーティ・コードへの参照を定義します。つまり、参照コンポーネントはコードに対するポインタ(NPMモジュールまたはCDN位置、あるいはその両方)です。参照コンポーネントは、実際にはサードパーティ・ライブラリを含んでおらず、ポイントしているだけです。

特定のアプリケーション・ニーズをサポートするには、スタンドアロンWebコンポーネントを作成できます。また、一緒に使用するためのWebコンポーネントのセットを作成してから、JETパックすなわちパック・コンポーネント・タイプとしてアセンブルすることもできます。パック・コンポーネントには、Webコンポーネントと、パック内の各コンポーネントのバージョン・ストライプを定義する構成ファイルが含まれます。Webコンポーネントがパックの一部である場合は、その定義ファイルを変更して、スタンドアロン・コンポーネントとして使用される同一コンポーネントと区別する必要があります。

ヒント:

少数のパックにコンポーネントをアセンブルすると、コンシューマの観点からは、パスの設定と依存関係の管理がかなり単純になります。

リソース・コンポーネントを使用してJETパック・コンポーネントを拡張できるのは、厳密にUIコンポーネントではないアセットの再利用可能なライブラリがあるときです。リソース・コンポーネントの構造には柔軟性があるため、共有イメージ、リソース・バンドル、ユーティリティ・クラスなど、必要なものを追加できます。

Webコンポーネントでサードパーティ・コードを参照する必要がある場合は、参照コンポーネントを作成できます。参照コンポーネントにサードパーティ・ライブラリは含まれませんが、そのコードに対するポインタをNPMモジュールまたはCDN位置(あるいは両方)として定義できます。所定のコンポーネントのパッケージ化ディストリビューションに、サードパーティ・ライブラリのコードを埋め込むことは可能ですが、分離することによって主に2つのメリットが得られます。

  • 依存関係が明確で、事前に宣言されます。サードパーティ・ライブラリおよびライセンスの使用に関心がある組織にとって、これは重要な考慮事項です。また、サードパーティ・コードのセキュリティの脆弱性への対処が非常に容易になります。

  • これらのライブラリ(特にmoment.jsなど共通ライブラリ)の再利用を最大限に活用できます。

パックに含めることができないコンポーネント・タイプは参照コンポーネントのみです。

JETパックを作成する際は、そのコンポーネントが、利用側アプリケーションとの関係において、時間経過とともにどのように変化するかを検討することが重要です。よくある間違いは、コンポーネントのバージョン番号と主要な利用側アプリケーションのバージョン番号を同期して開始することです。この関係は破綻する可能性があります。たとえば、いずれかのコンポーネントでの最新API変更によって、メジャー・バージョンが強制的に変更されると、同期しなくなります。ベスト・プラクティスは、最初からコンポーネントのセマンティック・バージョニング(SemVer)を使用し、利用側アプリケーションのバージョンと同期しないことです。SemVerの動作、特に再リリース・バージョンに関しては、理解できるまで時間をかけてください。詳細は、「バージョン採番の標準」を参照してください。

コンポーネント・セットのソース・コードは、それを使用するアプリケーションとは別に管理する必要があります。時間の経過に伴ってコンポーネントは利用側アプリケーションと違うペースで変化するため、ソース・コードを別のソース・コード・プロジェクトとリポジトリに分離することには大きな意味があることを忘れないでください。

コンポーネント・ソース・プロジェクトの推奨プロジェクト・レイアウトは、Oracle JET CLIツールによって作成されるデフォルト・プロジェクト・レイアウトに基づきます。JET CLIでは、TypeScriptコンポーネントおよび標準ES6ベース・コンポーネントの作成がサポートされます。JETツールによって生成されるプロジェクトのレイアウトに従うと、次のようなツールのメリットがあります。

  • コンポーネントとアップストリーム依存関係の正しいRequireJSパス・マッピングを自動作成(このコンポーネント・ソース・プロジェクトのコンテキストでテストするとき)

  • ojet serveコマンドを使用する際のライブ編集をサポート(JSおよびTSコンポーネント)

  • TypescriptベースのコンポーネントのES6への自動トランスパイル

  • ojet buildコマンドでデバッグ・コンポーネントと縮小コンポーネント両方を自動作成

  • JETパックのコンポーネント・バンドルを自動作成(バンドル化が指定されたとき)

  • Component Exchangeに直接公開する機能(ojet publishコンポーネント・コマンドを使用)

  • コンポーネントを配布可能なzipファイルに直接パッケージ化する機能(ojet packageコンポーネント・コマンドを使用)

Webコンポーネントについて

Oracle JET Webコンポーネントは、アプリケーションがRequireJSを使用してロードできるスタンドアロン・モジュールとしてパッケージ化されます。フレームワークは、Webコンポーネントの登録に使用できるAPIを提供します。Knockoutは、現在、一方向および双方向のデータ・バインディング、テンプレート・マークアップおよびWebコンポーネントのアクティブ化を提供しています。

Webコンポーネントを初めて利用する場合、さらに学習するには、Oracle Blogsページ(https://blogs.oracle.com/groundside/cca)にアクセスして、重要な概念について紹介する一連の記事を参照してください。

Webコンポーネント・アーキテクチャ

次の図に、JET Webコンポーネント・アーキテクチャの概要を示します。この例では、Oracle JETアプリケーションがWebコンポーネントを使用していますが、サポートされている他のJavaScriptまたはOracleアプリケーションにWebコンポーネントを追加できます。

Webコンポーネントに含まれるもの:

  • カスタムDOM要素: HTML要素として機能する、名前が付けられた要素。

    <my-web-component attribute1="value1" attribute2="value2" ...>
    </my-web-component> 
  • Webコンポーネント・バインディング定義: Webコンポーネントの属性を設定するためのKnockout式。

    <my-web-component attribute1="value1" attribute2="[[value2]]" attribute3="{{value3}}">
    </my-web-component> 

    attribute1の値はプリミティブJavaScript型(boolean、number、string)またはJSONオブジェクトのどちらかであり、attribute2の値は一方向データ・バインディングを使用し、attribute3の値は双方向バインディングを使用します。Webコンポーネントでの一方向バインディングは、値が変更された場合に式がアプリケーションのViewModelを更新しないように指定します。双方向バインディングでは、式はアプリケーションのViewModelを更新し、値がViewModelに書き戻されます。

    次のコード・サンプルでは、Webコンポーネントは、typedataおよびaxis-labelsという3つの属性を使用して宣言されています。

    <my-chart type=bubble data="[[salesData]]" axis-labels={{showAxisLabels}} ... </my-chart>

    salesData式は一方向バインディング([[salesData]])を使用して宣言されているため、WebコンポーネントのViewModelによってdataプロパティが更新された場合に書き戻されません。dataプロパティには現在の値が含まれますが、salesData式は更新されません。あるいは、axisLabelsプロパティがViewModelによって更新された場合、axisLabelプロパティと{{showAxisLabels}}式の両方に更新された値が含まれます。

  • メタデータ: Webコンポーネントの必須プロパティ(nameversionおよびjetVersion)を定義するオプションのJSON形式で提供されるデータ。メタデータでは、descriptiondisplayNamedependenciesiconmethodseventsおよびslotsなど、オプションのプロパティも定義できます。

    Webコンポーネントは、ランタイム・メタデータとデザインタイム・メタデータの両方をサポートしています。デザインタイム・メタデータは実行時には必要なく、デザインタイム・ツールやプロパティ・エディタで役立ちます。デザインタイム・ツールでは、Webコンポーネントのメタデータに対してツール固有のメタデータ拡張機能を定義できます。ツール固有のメタデータ拡張機能については、その固有のツールのドキュメントを参照してください。メタデータ・プロパティの詳細は、APIドキュメントの Compositeに関する項を参照してください。

    次のサンプルは、いくつかの使用可能なメタデータ・フィールドと、その内容および実行時に使用されていないかどうかに関する説明を示しています。必須のメタデータは太字で強調表示されています。

    {
      "name": "The component tag name",
      "version": "The component version. Note that changes to the metadata even for minor updates like updating the jetVersion should result in at least a minor Web Component version change, e.g. 1.0.0 -> 1.0.1.",
      "jetVersion": "The semantic version of the supported JET version(s). Web Component authors should not specify a semantic version range that includes unreleased JET major versions as major releases may contain non backwards compatible changes. Authors should instead recertify Web Components with each major release and update the component metadata or release a new version that is compatible with the new release changes.",
      "description": "A high-level description for the component. Not used at run time.",
      "displayName": "A user friendly, translatable name of the component. Not used at run time.",
    
      "properties": {
        "property1": {       
          "description": "A description for the property. Not used at run time.",
          "displayName": "A user friendly, translatable name of the property. Not used at run time.",
          "readOnly": "Boolean that determines whether a property can be updated outside of the ViewModel. False by default.",
          "type": "The type of the property, following Google's Closure Compiler syntax.",
          "value": "Object containing an optional default value for a property.",
          "writeback": "Boolean that determines whether an expression bound to this property should be written back to. False by default.",
          "enumValues": "An optional array of valid enum values for a string property. An error is thrown if a property value does not match one of the provided enumValues.",
          "properties": "A nested properties object for complex properties. Subproperties exposed using nested properties objects in the metadata can be set using dot notation in the attribute. See the Subproperties section for more details on working with subproperties."
          },
    
        "property2": {
             ... contents omitted
          }
      },
    
      "methods": {
        "method1": {   
          "description": "A description for the method. Not used at run time.",
          "displayName": "A user friendly, translatable name of the method. Not used at run time.",
          "internalName": "An optional ViewModel method name that is different from, but maps to this method.",
          "params": "An array of objects describing the method parameter . Not used at run time.",
          "return": "The return type of the method, following Closure Compiler syntax. Not used at run time."
         },
        "method2": {
         ... contents omitted
         }
      },
    
      "events": {
        "event1": {
          "bubbles": "Boolean that indicates whether the event bubbles up through the DOM or not. Defaults to false. Not used at run time.",
          "cancelable": "Boolean that Indicates whether the event is cancelable or not. Defaults to false. Not used at run time.",
          "description": "A description for the event. Not used at run time.",
          "displayName": "A user friendly, translatable name of the method. Not used at run time.",
          "detail": {
            "field name": "Describes the properties available on the event's detail property which contains data passed when initializing the event. Not used at run time."
           }
         }, 
        "event2": {
         ... contents omitted
         } 
       },
    
      "slots": {
        "slot1": {
          "description": "A description for the slot. Not used at run time.",
          "displayName": "A user friendly, translatable name of the method. Not used at run time."
         }
       }
    }
    
  • HTMLマークアップ: (必須) Webコンポーネントのレンダリング方法について説明するView定義が含まれます。WebコンポーネントのViewは、WebコンポーネントのViewModelで定義されたpublic変数とともに、いくつかの$変数にアクセスします。次に、WebコンポーネントのViewで使用できる変数の一部を示します。

    変数 説明
    $properties Webコンポーネントの現在のプロパティ値のマップ
    $slotCounts スロットに割り当てられた関連付けられた子ノードの数を含むスロット名のマップ
    $unique 一意のID生成に使用できる各コンポーネント・インスタンスに指定される一意の文字列値
    $uniqueId WebコンポーネントのID (指定された場合)。指定されない場合はuniqueと同じ
    $props 5.0.0以降では非推奨のため、かわりに$propertiesを使用
    $slotNodeCounts 5.0.0以降では非推奨のため、かわりに$slotCountsを使用
  • JavaScript: ViewModelおよびカスタム・イベントを定義するためのオプションのスクリプト。

    ViewModelでは、Webコンポーネントのライフサイクルの様々なステージのコールバックも定義します。Webコンポーネントは、オプションで次のライフサイクル・メソッドをサポートしています: activated (context)connected (context)bindingsApplied (context)propertyChanged (context)およびdisconnected (element)。ライフサイクル・メソッドの詳細は、Composite - Lifecycleに関する項を参照してください。

  • CSS: Webコンポーネントのオプションのスタイル設定。

    CSSはWebコンポーネントをスコープとしていないため、適切にスタイルを定義する必要があります。

  • SCSS: Sass変数を含んだオプションのファイルで、WebコンポーネントのCSSを生成します。

    コンポーネントに対して2、3のスタイルしか定義しないとき、手動でCSSを追加することで十分な場合があります。ただし、Sass変数を使用してCSSを生成したいユースケースもあります。それらの場合、SCSSファイルを作成し、Webコンポーネントのフォルダ内に置き、ツールを使用してアプリケーションにnode-sassを追加します。ステップ8「Webコンポーネントの作成」を参照してください。

    重要:

    Sassファイルは手動でWebコンポーネントのフォルダに追加する必要があります。ツールでは存在するすべてのSassファイルがコンパイルされますが、自動的には作成されません。

Webコンポーネント・ファイル

Webコンポーネントには、アプリケーション要件に応じて変更可能なCSS、HTML、JavaScriptおよびメタデータ・ファイルを含めることができます。

フォルダを作成し、必要なファイルをフォルダ内に追加することによって、Webコンポーネントを手動で作成できます。アプリケーションに必要なファイルを含むWebコンポーネント・フォルダを自動的に生成するOracle JET CLIコマンドojet create component <component-name>を使用して、Webコンポーネントを作成することもできます。

Webコンポーネントを手動で作成する場合は、Webコンポーネント・タグと同じ名前のWebコンポーネント・ファイルをフォルダに配置します。通常、フォルダはアプリケーション内のjet-compositesフォルダ(app-path/jet-composites/my-web-component/)に配置します。

Webコンポーネントを別のファイル・ロケーションに置くことや、RequireJSパス・マッピングを使用して別のサーバー上のWebコンポーネントを参照することもできます。例として、Composite - パッケージ化と登録に関する項を参照してください。

各Webコンポーネント・ファイルには、次のように目的と一致する命名規則を使用してください。
  • my-web-component—view.html: ビュー・テンプレート

  • my-web-component—viewModel.js: ViewModel

  • component.json: メタデータ

  • my-web-component-styles.css: CSSスタイル設定

  • my-web-component-styles.scss: Webコンポーネント用のCSSを生成するためのSass変数

  • loader.js: メタデータ、View、ViewModelおよびCSSの依存性を定義するRequireJSモジュール。このファイルにはWebコンポーネントの登録も含める必要があります。

Webコンポーネントのスロッティング

スロットは、ユーザーがマークアップで入力できるWebコンポーネントのプレースホルダとして使用されます。スロットは、WebコンポーネントのコンポーネントJSONファイルで定義されます。

スロッティングを使用して、WebコンポーネントのViewマークアップ内の指定した場所に挿入する子コンポーネント(これもWebコンポーネントになる可能性があります)を追加します。次の例には、demo-columnsという名前のWebコンポーネントのViewマークアップの一部が含まれています。

<div class="oj-flex oj-flex-item-pad">
  <div role="group" :aria-label="[[$properties.headers[0]]]"
   class="oj-flex-item demo-columns-col-a oj-flex oj-sm-flex-direction-column oj-sm-align-items-center">
    <h3>
			<oj-bind-text value="[[$properties.headers[0]]]"></oj-bind-text>
		</h3>
		<oj-bind-slot name="columnA">
		</oj-bind-slot>
 	</div>
  ... content omitted
</div>

この例では、demo-columns Webコンポーネントは、columnAという名前でoj-bind-slotを定義しています。次に示すように、demo-columns Webコンポーネントをページに追加するとき、開発者はcolumnAという名前のスロットを使用して子コンポーネントを指定できます。

<demo-columns id="composite-container" headers='["Sales", "Human Resources", "Support"]'>
  <!-- ko foreach: sales -->
    <demo-card slot="columnA" name="[[name]]" work-title="[[title]]"></demo-card>
  <!-- /ko -->
  ... contents omitted
</demo-columns>

Webコンポーネントのテンプレート・スロット

コンポーネントのマークアップ内でtemplate要素が使用されている場合、テンプレート・スロットを使用してテンプレート内にプレースホルダを定義し、そこに必要なマークアップ・フラグメントを挿入できます。

スタンプ済のテンプレートを異なるデータで再利用する必要がある場合は、テンプレート・スロットを使用してコンポーネントのバインディング・コンテキストから追加データを表示できます。

コンポーネントのマークアップ内でtemplate要素が使用されている場合、テンプレート・スロットを使用してテンプレート内にプレースホルダを定義し、そこに必要なマークアップ・フラグメントを挿入できます。スタンプ済のテンプレートを異なるデータで再利用する必要がある場合は、テンプレート・スロットを使用してコンポーネントのバインディング・コンテキストから追加データを表示できます。

Webコンポーネントのテンプレート・スロットは、アプリケーション内で挿入されるコンテンツ用に追加のバインディング・コンテキストを定義する場合に使用されます。テンプレート・スロットを宣言的に定義する場合は、WebコンポーネントのViewマークアップ内で、スタンプ済のテンプレートDOMが含まれるスロットにoj-bind-template-slot要素を使用します。oj-bind-template-slot要素はoj-bind-slot要素と似ていますが、挿入されるコンテンツはアプリケーションDOM内でtemplate要素の内部にラップされる必要があります。

次の例では、demo-list Webコンポーネントでitemという名前のoj-bind-template-slotを定義します。このテンプレート・スロットは、追加プロパティをテンプレートDOMに表示するdata属性と、$current変数の別名として使用されるdata-oj-as属性を備えています。template要素のdata-oj-as属性は、デフォルト・テンプレートの内部でのみ参照可能です。

<table>
  <thead>
    <tr>
      <th>
        <oj-bind-text value="[[$properties.header]]"></oj-bind-text>
      </th>
    </tr>
  </thead>
  <tbody>
    <oj-bind-for-each data="{{$properties.data}}">
      <template>
        <tr>
          <td>
            <!-- Template slot for list items with default template and an optional alias -->
            <oj-bind-template-slot name="item" data="{{'value': $current.data}}">
              <!-- Default template -->
              <template data-oj-as="listItem">
                <span>
                 <oj-bind-text value='[[listItem.value]]'</oj-bind-text>
                </span>
              </template>
            </oj-bind-template-slot>
          </td>
        </tr>
      </template>
    </oj-bind-for-each>
  </tbody>
  ... contents omitted
</table>

oj-bind-template-slotの子は、WebコンポーネントのViewバインディングの適用時に解決され、その後で、Webコンポーネント提供の追加プロパティで拡張されたアプリケーションのバインディング・コンテキストで解決されます。これらの追加プロパティは、アプリケーション指定のテンプレート・スロット内で$current変数に対して使用できます。アプリケーションは、テンプレート内で、$current変数のかわりにオプションのdata-oj-as属性を別名として使用できます。次の例には、demo-listという名前のアプリケーションのマークアップの一部が含まれています。

<demo-list data="{{groceryList}}" header="Groceries">
 <template slot="item" data-oj-as="groceryItem">
   <oj-checkboxset>
     <oj-option value="bought"><oj-bind-text value='[[groceryItem.value]]'></oj-bind-text></oj-option>
   </oj-checkboxset>
 </template>
... contents omitted
</demo-list>

Oracle JETクックブックのWebコンポーネントのテンプレート・スロットに関する項には、テンプレート・スロットを使用するための完全な例があります。oj-bind-template-slot APIドキュメントでは、属性およびテンプレート・スロットのその他のプロパティについて説明しています。

Webコンポーネント・イベント

Oracle JET Webコンポーネントは、コンポーネント・メタデータに定義されているプロパティにマップされた自動プロパティ変更イベントを起動できます。これらのコンポーネントは、コンポーネント・メタデータで宣言されているイベントに対してもカスタム・イベントを起動します。

Webコンポーネントは、propertyChangedライフサイクル・メソッドを使用して、コンポーネント・メタデータのプロパティにマップされている自動生成されたpropertyChangedイベントを内部的にリスニングできます。たとえば、propertyChangedイベントは、プロパティの更新時に起動されます。このpropertyChangedイベントには、次のプロパティが含まれます。

  • property: 変更されたプロパティの名前。

  • value: プロパティの現在の値。

  • previousValue: 変更されたプロパティの前の値。

  • updatedFrom: プロパティの更新元となった場所。

  • Subproperty: 変更されたサブプロパティに関する情報を保持するオブジェクト。

Webコンポーネントに対してカスタム・イベントを宣言的に定義する必要がある場合は、コンポーネントのメタデータ・ファイルでそのイベントを宣言する必要があります。これらのイベントは、WebコンポーネントのコードがdispatchEvent()メソッドをコールした場合にのみ起動されます。アプリケーションは、イベント・リスナー属性とプロパティ・セッターを宣言することで、これらのイベントをリスニングできます。これらのイベント・リスナーは、宣言的またはプログラム的に追加できます。

イベント・リスナーの宣言的仕様については、属性にon-[event-name]構文を使用します。たとえば、on-clickon-value-changedなどです。

<oj-element-name value="{{currentValue}}" on-value-changed="{{valueChangedListener}}"></oj-element-name>

イベント・リスナーのプログラム仕様では、DOM addEventListenerメカニズムを使用するか、カスタム要素プロパティを使用できます。

DOM addEventListenerメカニズムでは、elementName.addEventListenerメソッドを使用します。たとえば:

elementName.addEventListener("valueChanged", function(event) {...});

カスタム要素プロパティでは、プロパティ・セッターに対してelementName.onEventName構文を使用します。たとえば:

elementName.onValueChanged = function(event) {...};

詳細は、Webコンポーネントのイベントとリスナーに関する項のAPIドキュメントを参照してください。

Webコンポーネントの例

Webコンポーネントには、スロット、データ・バインディング、テンプレート・スロット、ネストされたWebコンポーネントおよびイベントを含めることができます。これらのWebコンポーネントの機能については、Oracle JETクックブックに提供されている例を使用できます。

Oracle JETクックブックには、基本的および高度なWebコンポーネントを作成するための完全な例があります。また、スロッティングおよびデータ・バインディングを使用した例もあります。詳細は、「Webコンポーネント - 基本」を参照してください。

Webコンポーネントのフィールドおよびメソッドの詳細は、APIドキュメントの Compositeに関する項を参照してください。

Webコンポーネント作成のベスト・プラクティス

Oracle JET Webコンポーネントを作成するためのベスト・プラクティスには、必須および推奨のパターン、構成、コーディング事例、バージョン採番およびスタイリング標準が含まれています。ベスト・プラクティスを実践することにより、他のコンポーネントおよびコンシューマ・フレームワークとの相互運用性を確保します。

推奨される標準パターンとコーディング・プラクティス

Oracle JET Webコンポーネント用の推奨パターンおよびコーディング事例には、構成、バージョニング、コーディング、およびアーカイブのための標準が含まれています。

コンポーネントのバージョニング

Webコンポーネントには、セマンティック・バージョン形式でバージョン番号を割り当てる必要があります。

コンポーネントに関連付けられたバージョン番号の割当てや増分を行うときは、必ずセマンティック・バージョンのルールに従って適切にメジャー、マイナーおよびパッチ・バージョン番号を更新してください。こうすることで、コンポーネントのコンシューマがコンポーネントの異なるバージョン間の移行に伴う互換性とコストを明確に理解できるようになります。

Webコンポーネントにバージョン番号を割り当てるには、セマンティック・バージョニングについてを参照してください。

JETバージョンの互換性

サポートされているJETバージョンのjetVersionを指定するには、セマンティック・バージョンのルールを使用する必要があります。メジャー・リリースには下位互換性のない変更が含まれている可能性があるため、Webコンポーネントの作成者は未リリースのJETメジャー・バージョンを含むセマンティック・バージョン範囲を指定しないでください。かわりに、作成者はメジャー・リリースごとにWebコンポーネントを再認定して、コンポーネントのメタデータを更新するか、または新しいリリースの変更と互換性がある新しいバージョンをリリースするようにしてください。

翻訳可能なリソース

Webコンポーネントの翻訳可能なリソースをローカライズする開発者は、Webコンポーネントの作成時にリソース・バンドル(テンプレート)を取得できるようになりました。これらのコンポーネントでは、ojL10n requireJSプラグインを使用して標準のOracle JETメカニズムを使用する必要があります。翻訳バンドルは、Webコンポーネントのフォルダのリソース文字列を含むwebcomponentname/resources/nls/rootサブディレクトリのピアであるwebcomponentname/resources/nlsサブディレクトリに格納する必要があります。Webコンポーネントのメタデータでサポートする言語とロケールを宣言できます。

ピア・ツー・ピア通信

コンポーネントで複雑な統合を処理する場合は、どんな種類のシークレット伝達メカニズムよりも、コンシューマが提供する共有のobservableを優先する必要があります。たとえば、フィルタ・コンポーネントやデータ表示コンポーネントなどです。共有のobservableを使用することで、コンポーネントを事前にシードし、プログラムでフィルタを介してコンポーネントと対話できます。

または、使用されている次のいずれかのアプローチに基づいてイベントとパブリック・メソッドを使用できます。

  • イベントのソースと受信側の階層関係

  • 受信側に渡されるソースのアイデンティティ

    一部のランタイム・プラットフォームでは、ワイヤリングを行う開発者がコンポーネントのIDにアクセスできず、関連するアイデンティティを渡せない場合があることに注意してください。

  • コンポーネントがドキュメント・レベルでアタッチしたリスナー

    この場合は、これらのリスナーのクリーン・アップや重複の管理などを行う責任があります。また、このようなリスナーは、中間ノードによってオーバーライドされる可能性があるクリックなどの一般的なイベントではなく、Webコンポーネント・イベントに基づいて定義することをお薦めします。

ノート:

Webコンポーネントの標準(Shadow DOM)では、イベントがコンポーネントとコンシューマのビュー間の境界を越えるときに、イベントのターゲットが再設定されます。つまり、発生元の要素の見かけ上のアイデンティティが変更される可能性があります。特に、ネストされているWebコンポーネント・アーキテクチャでは、内側のWebコンポーネントではなく外側のWebコンポーネントを表す要素でイベントがタグ付けされます。したがって、ドキュメント・レベルでリスニングする場合は、event.target属性を使用してWebコンポーネント・ソースのアイデンティティを識別しないでください。かわりに、event.deepPath属性を使用してイベントの実際のオリジンを確認できます。

外部データへのアクセス

Webコンポーネントでは、Knockoutバインディング階層を使用してWebコンポーネントのコンテキストの外部($root$parent[1]など)からデータを取得できません。コンポーネントに出入りするすべてのデータ転送は、正式なプロパティ、メソッドおよびイベントを使用して行う必要があります。

オブジェクト・スコープ

Webコンポーネントのすべてのプロパティおよび関数は、ビュー・モデルのスコープに限定する必要があります。ウィンドウ・スコープ・オブジェクトやグローバル・スコープ・オブジェクトは作成しないでください。同様に、Webコンポーネントの作成者はウィンドウ・スコープ・オブジェクトの存在を前提としないでください。ウィンドウ・レベルまたはグローバル・レベルで外部定義されたコンシューマWebコンポーネントが読取りや書込みのために必要な場合は、コンシューマのビュー・モデルが正式なプロパティを使用してそのコンポーネントを渡す必要があります。コンポーネントの外部で既知のグローバル参照が必要な場合でも、必須のdefine()関数を使用して正式に参照を挿入し、Webコンポーネントのメタデータで参照を依存性として宣言する必要があります。

外部参照

Webコンポーネントから外部コンポーネントを参照する必要がある場合は、それをコンポーネントの正式なAPIの一部にする必要があります。この正式なAPIは、プロパティを介してコンポーネント参照を渡します。たとえば、Webコンポーネント・コードでリスナーを登録できるようにするには、外部で定義されたコンポーネント参照が必要です。Webコンポーネントでハードコードされた値、グローバル・ストレージ、またはDOMの検索結果からIDを取得しないでください。

サブコンポーネントID

フレームワーク内に特定のIDを必要とするコンポーネントがある場合は、context.uniqueまたはcontext.uniqueIdの値を使用してIDを生成します。このIDは、ページのコンテキスト内で一意です。

IDの格納

生成されたIDを呼出しにまたがってローカル・ストレージやCookieなどに格納しないでください。特定のWebコンポーネントのcontext.uniqueの値は、特定のビューが実行されるたびに変更される可能性があります。

ローカル・ストレージ

アプリケーション内でWebコンポーネントの一意のインスタンスを一貫して識別するのは困難です。そのため、Webコンポーネントがブラウザのローカル・ストレージを使用して、そのWebコンポーネントのインスタンスに特有の情報を保持しないようにすることをお薦めします。ただし、アプリケーションがコンポーネントのパブリック・プロパティを介して一意のキーを提供する場合は、コンポーネントの一意のインスタンスを識別できます。

また、ローカル・ストレージをコンポジット間のシークレット伝達メカニズムとして使用しないでください。この機能の可用性を保証できないため、コンポーネントのパブリックAPIの一部である共有のJavaScriptオブジェクトまたはイベントを介して情報を交換することをお薦めします。

文字列のオーバーライド

多くの場合、WebコンポーネントはUIやメッセージに対するデフォルトのニーズに対応するため、内部で文字列リソースを取得します。しかし、場合によっては、コンシューマがこれらの文字列をオーバーライドできるようにする必要があります。そのためには、コンポーネントでこの目的に合うプロパティを公開します。慣例により、このようなプロパティはtranslationsと呼ばれ、その内部に、コンポーネントの必須プロパティに関連する個々の翻訳可能文字列(requiredHintrequiredMessageSummaryなど)に対応するサブプロパティを含めることができます。これらのプロパティは、コンポーネント・タグでサブプロパティ参照を使用して設定できます。たとえば:

"properties" : {
  "translations": {
    "description": "Property to allow override of default messages",
    "writeback" : false, 
    "properties" : {
      "requiredHint": {
        "description": "Change the text of the required hint", 
        "type": "string"
         },
      "requiredMessageSummary": {
        "description": "...",
        "type": "string"
        },  
      "requiredMessageDetail": {
          "description": "...",
          "type": "string"
        } 
      }
     } 
   }
}

ロギング

console.log()に優先してコードからログ・メッセージを書き込むには、Loggerを使用します。Webコンポーネントでは、利用側アプリケーションのロギング・レベルを尊重し、変更しないでください。コンポーネントから発行されたすべてのログ・メッセージの先頭にソースWebコンポーネントのIDを付けるのが理想的です。プリファレンスとして、Webコンポーネント名を使用できます。利用側アプリケーションで定義されたライターをコンポーネントでオーバーライドしないでください。

高コストの初期化

Webコンポーネントでは、コンストラクタ関数の内部で実行する処理を最小限に抑える必要があります。コストの高い初期化は、activated以降のライフサイクル・メソッドまで延期してください。コンポーネントが実際には表示可能なDOMに追加されていない場合でも、Webコンポーネントのコンストラクタは呼び出されます。たとえば、Knockoutのifブロック内でコンストラクタが呼び出された場合などです。以降のライフサイクル・フェーズは、コンポーネントが実際に必要になった場合にのみ発生します。

サービス・クラス

グローバル・サービス・クラスの使用、つまり複数のWebコンポーネントで共有される機能により、Webコンポーネントのコンシューマが知る必要がある非表示の規約を構成することができます。これを回避するため、次のようにすることをお薦めします。

  • すべてのWebコンポーネントが明示的にrequire()ブロックとして設定できるモジュールとしてサービスを作成します。これにより、コンシューマは他の場所でこのサービスを実行する必要がなくなります。

  • サービス・クラスの初期化(リモート・サービスからのデータのフェッチなど)に時間がかかる場合に発生するタイミングの問題を考慮してください。このような場合は、サービス・オブジェクトにPromiseを返して、情報が実際に利用可能になる前にコンポーネントが情報の使用を安全に回避できるようにする必要があります。

ojModuleの使用

WebコンポーネントでojModuleを使用し、アプリケーションの外部にWebコンポーネントを配布する場合は、Webコンポーネントの場所を基準にした相対的な場所から使用するojModuleをロードするための追加ステップを実行する必要があります。ViewおよびViewModelインスタンスをojModuleに直接渡さない場合は、必須関数インスタンスとビューおよびビュー・モデルの相対パスを提供する必要があります。必須関数インスタンスは、Webコンポーネント・ローダー・モジュールで依存性としてrequireを指定することで取得する必要があります。

<div data-bind="ojModule: {require: {instance: require_instance, viewPath: "path_to_Web_Component_Views", modelPath: "path_to_cWeb_Component_ViewModels"}}"></div> 
requireオプション タイプ 説明

instance

関数

必須インスタンスを定義する関数

viewPath

文字列

WebコンポーネントのViewへのパスを含む文字列

modelPath

文字列

WebコンポーネントのViewModelへのパスを含む文字列

ojModuleの使用の詳細は、 ojModuleを参照してください。

配布用のWebコンポーネントのアーカイブ

パッケージ化のためにzipファイルを作成する場合は、コンポーネント自体と同じ名前でアーカイブを作成します。操作上の理由でzipファイル名にバージョンを識別するための接尾辞を追加することもできます。Webコンポーネントのアーティファクトは、zipファイルのルートに配置する必要があります。ファイルに到達するまでの中間にディレクトリ構造を作成しないでください。

ライフサイクル・メソッドの使用

WebコンポーネントにViewModelが指定されている場合は、Webコンポーネントのライフサイクルの各ステージでコールされる次のコールバック・メソッドを、そのViewModelにオプションで定義できます。使用可能なコールバック・メソッドの一部を次に示します。

  • activated(context): ViewModelが初期化された後に呼び出されます。

  • connected(context): ViewがDOMに最初に挿入された後に呼び出され、以降はWebコンポーネントが切断された後でDOMに再接続されるたびに呼び出されます。

  • bindingsApplied(context): バインディングがViewに適用された後に呼び出されます。

  • propertyChanged(context): プロパティの更新時、[property]Changedイベントが発生する前に呼び出されます。

  • disconnected(element): このWebコンポーネントがDOMから切断されるときに呼び出されます。

Webコンポーネントのライフサイクル・メソッドの詳細は、Composite - Lifecycleに関する項を参照してください。

テンプレートの別名

インライン・テンプレートをサポートするJETコンポーネントでは、オプションのdata-oj-as属性を使用して、$current変数にテンプレート固有の別名をアプリケーション・レベルで指定できるようになりました。チャート・コンポーネントや表コンポーネントなど、コンポーネントで複数のテンプレート・スロットをサポートする必要があるインスタンスでは、1つの別名では不十分な場合があります。このような場合は、template要素でオプションのdata-oj-as属性を使用できます。テンプレート・スロットでこのオプション属性を使用する方法の詳細は、oj-bind-template-slot APIドキュメントを参照してください。

CSSおよびテーマ適用の標準

Oracle JET Webコンポーネントは、他のWebコンポーネントおよび利用側アプリケーションとの相互運用性を確保するため、推奨されるスタイリング標準のすべてに準拠する必要があります。

CSSおよびテーマを使用する際の一般的なベスト・プラクティスの詳細は、「CSSおよびテーマを使用するためのベスト・プラクティス」を参照してください。

標準 詳細

スタイルが設定されていないコンテンツのフラッシュを防止する

Oracle JETは、メタデータ・プロパティが解決された後、oj-completeクラスをWebコンポーネントDOM要素に追加します。コンポーネント・プロパティが設定される前の、スタイルが設定されていないコンテンツのフラッシュを防止するには、コンポーネントのCSSに、oj-completeクラスが要素で設定されるまでの間、コンポーネントを非表示にするルールを含める必要があります。

これは要素セレクタであり、acme-brandingの前にドット(.)があってはならないことに注意してください。

acme-branding:not(.oj-complete) {
  visibility: hidden;
}

スコープ指定の追加

要素セレクタを使用して、あなたのコンポーネントの外部でクラスの1つが誰かに使用され、あなたが行った内部の実装に依存するようになる可能性を最小限に抑えます。右側の例で、acme-brandingタグの中にないクラスacme-branding-headerを適用しても、無効です。

acme-branding .acme-branding-header {
  color: white;
  background: blue;
}

重要: コンポーネントにダイアログも含まれている場合、表示時にそのダイアログはメイン・ドキュメントのDOMツリーにアタッチされ、Webコンポーネントの子にはなりません。したがって、コンポーネントで定義されたダイアログに適用するスタイルを定義する場合、コンポーネントはダイアログ表示時の実際のコンテナではないため、コンポーネント名に対してスコープ指定できません。

これを解決するには、かわりにコンポーネント名を接頭辞として使用します。

.acme-branding-dialog-background{
  color: white;
  background: blue;
}

要素のスタイリングの回避

アプリケーションは、ヘッダーやリンクなどのHTMLタグ要素をスタイリングすることがよくあります。アプリケーションとの調和のため、Webコンポーネントでこれらの要素をスタイリングしないようにします。

警告アイコンヘッダーなどの要素のスタイリングは避けてください。

acme-branding .acme-branding-header h3{
  font-size: 45px;
}

バージョン採番の標準

すべてのタイプのWebコンポーネント(スタンドアロン・コンポーネント、JETパック、リソース・コンポーネントなど)にはバージョン番号が必要であり、この番号はセマンティック・バージョニング(SemVer)スキームに準拠する必要があります。そうすることで、開発チームの標準がOracle JETリリース・バージョン管理で採用されたアプローチに従うことになります。

参照コンポーネントは少し特別なケースです。参照コンポーネントのバージョンは、それが参照しているNPMライブラリのバージョンと必ず一致するためです。

他のすべてのWebコンポーネント・タイプは、セマンティック・バージョニングを利用してコンポーネントのバージョンを指定します。セマンティック・バージョニングで定義されるバージョン番号には、3つの主要セグメントとオプションの4つ目のセグメントが含まれます。最初の3つのセグメントはMAJOR.MINOR.PATCHと定義され、意味は次のとおりです。

  • MAJORバージョン: 互換性のないAPI変更を行うとき

  • MINORバージョン: 下位互換性を維持して機能を追加するとき

  • PATCHバージョン: 下位互換性があるバグ修正を行うとき

ノート:

セマンティック・バージョニングの背景情報は、https://semver.orgを参照してください。

Webコンポーネントのバージョン番号を定義するときは、これら3つの主要セグメントをすべて定義する必要があります。

1.0.0

さらに、PATCHバージョンの後に、2種類の追加情報を含むオプションの拡張セグメントを付けることができます。

  • ハイフンの後のセグメント(プレリリース・バージョンを割り当てることができる)

  • プラス記号(+)の後のセグメント(純粋に情報のみ、GITコミット・ハッシュや他の制御情報を含めることができる)。このセグメントは、コンポーネント・バージョンの比較には使用されません。

次に示すのは、コンポーネントのプレリリース・バージョンのすべてが定義されたバージョン番号の例です。

1.0.1-beta.1+332

このケースでは、beta.1がプレリリース・インジケータ、332がビルド番号です。

Webコンポーネントのバージョン番号の変更により、新しいバージョンを使用するリスク・レベルをコンシューマに示す必要があります。コンシューマは、コードを修正せずにコンポーネントの新しいMINORリリースまたはPATCHリリースを組み込むことができるかどうかを認識する必要があります。Webコンポーネントのソース・コードを変更することで、WebコンポーネントのディレクトリのリフレッシュまたはCDN参照の変更以外の処理を利用側アプリケーションが強制される場合は、MAJORバージョンを改訂してそのことを示す必要があります。

Webコンポーネント・メタデータ・ファイルcomponent.jsonを使用して、コンポーネントが使用できるOracle JETのサポートされるバージョンを定義できます。これがjetVersion属性であり、npm-semverで定義される特定のバージョンまたはバージョン範囲を設定できます。たとえば、jetVersion属性に次のいずれかを設定できます。

  • 推奨: MAJORリリース番号の変更が行われるまでのすべてのMINORバージョンとPATCHバージョン。たとえば、"jetVersion:: "^9.1.0"です。そのリリースと、次のMAJORリリースまでの(このMAJORリリースは含まれない)それ以降すべてのMINORバージョンとPATCHバージョンがサポートされることを示します。これは、">=9.1.0 <10.0.0"と同じです。

  • WebコンポーネントがサポートするOracle JETの正確なバージョンの正確なセマンティック・バージョン。たとえば、"jetVersion" : "9.1.0"です。このWebコンポーネントではOracle JET 9.1.0のみがサポートされることを意味します。

  • Oracle JETの特定のMAJOR.MINORリリース内のすべてのPATCHバージョン。たとえば、"jetVersion" : "9.0.x"です。このWebコンポーネントではJET 9.0.0からJET 9.1.0の前まで(JET 9.1.0そのものは含まれない)のJETのすべてのリリースがサポートされることを意味します。

  • Oracle JETバージョンの特定の範囲。たとえば、"jetVersion" : "9.0.0 -9.1.0"です。このWebコンポーネントではJET 9.0.0からJET 9.1.0までのJETのすべてのリリースがサポートされることを意味します(つまりJET 9.2.0やJET 8.0.0などは含まれません)。

ヒント:

Oracle JETの推奨形式は、"^9.1.0"のように定義される最初のケースです。JETそのものがセマンティック・バージョニング・ルールに従っているため、MINORバージョンまたはPATCHバージョンの変更により、Webコンポーネントのソース・コードが影響を受けることはありません。つまり、Oracle JETのMINORリリースごとに、すべてのWebコンポーネントの更新をリリースする必要がないことを意味します(新機能を使用することを選択しない場合)。

ノート:

npm-semverの背景情報は、このWebサイト(https://docs.npmjs.com/about-semantic-versioning)にあるnpmのドキュメントを参照してください。

JETパックの場合は、パックに含まれるcomponent.jsonファイルのdependencies属性に注意する必要があります。パックにバンドルされている様々なコンポーネントは一緒に使用されるようにしてください。そのように指定するために、バージョン範囲ではなく特定のバージョンとの依存関係を定義する必要があります。たとえば、このケースでは、バージョン1.0.2のdemo-memory-gameコンポーネントがホストするのはバージョン1.0.2のdemo-memory-cardのみです。

{
  "name": "demo-memory-game",
  "version": "1.0.2",
  "type": "pack",
  "displayName": "JET Memory Game",
  "description": "A memory game element with a configurable card set and attempt counter.",
  "dependencies": {
    "demo-memory-card": "1.0.2"
    }
}

Webコンポーネントの作成

Oracle JETでは、カスタムWebコンポーネントの様々なコンポーネント・タイプがサポートされます。スタンドアロンWebコンポーネントを作成できます。または、一緒に使用するためのWebコンポーネントのセットを作成できます。その後、それらをJETパックすなわちパック・コンポーネント・タイプとしてアセンブルできます。リソース・コンポーネントを作成してJETパックを拡張できるのは、厳密にUIコンポーネントではないアセットの再利用可能なライブラリがあるときです。また、スタンドアロン・コンポーネントでサードパーティ・コードを参照する必要がある場合は、参照コンポーネントを作成して、そのコードへのポインタを定義できます。

スタンドアロンWebコンポーネントの作成

Oracle JETコマンドライン・インタフェース(CLI)を使用して、JavaScriptまたはTypeScriptとして実装されるOracle JET Webコンポーネント・テンプレートを作成し、コンテンツを移入できます。ツールを使用しない場合、WebコンポーネントのファイルとフォルダをOracle JETアプリケーションに手動で追加できます。

次の図は、demo-cardという名前の単純なWebコンポーネントを示しています。このコンポーネントは、連絡先の名前と画像(もしあれば)を備えた連絡先カードを表示します。ユーザーがカードを選択すると、コンテンツが裏返り、連絡先に関するその他の詳細が表示されます。

次の手順は、このdemo-cardコンポーネントを例として使用した、Webコンポーネントを作成するための大まかなステップのリストです。簡潔さを優先してコードの一部を省略していますが、Webコンポーネントの基礎に関する項で完全な例を参照できます。デモ・ファイルは、クックブックのダウンロード・ボタン(デモのダウンロード・アイコン)をクリックすればダウンロードできます。

始める前に:

Webコンポーネントを作成するには:

  1. Webコンポーネントの名前を決定します。
    Webコンポーネントの仕様では、カスタム要素の名前が次のように制限されます。
    • 名前にはハイフンを含める必要があります。

    • 名前は小文字のASCII文字で始める必要があります。

    • 名前には大文字のASCII文字を使用できません。

    • 他のコンポーネントの名前と競合するリスクを減らすため、名前には一意の接頭辞を含めるようにしてください。

      お薦めのパターンとしては、コンポーネント名の最初のセグメントとして組織の名前を使用します。たとえば、org-component-name。名前は、予約済のojおよびnsネームスペースのルートに対応する接頭辞oj-またはns-で始めることはできません。

    • 名前には予約名を使用できません。Oracle JETでは、ojおよびnsのネームスペースと接頭辞も予約されています。

    たとえば、demo-cardを使用して連絡先カードの例の複製を作成します。

  2. 次のいずれかのオプションを使用して、Webコンポーネントの配置先を決定します。
    • Oracle JET CLIで作成した既存のOracle JETアプリケーションにWebコンポーネントを追加します。

      この方法を使用する場合は、CLIを使用して、Webコンポーネントのコンテンツを格納するために必要なフォルダとファイルを含むWebコンポーネント・テンプレートを作成します。

    • Oracle JET CLIを使用しない既存のOracle JETアプリケーションにWebコンポーネントを手動で追加します。

      この方法を使用する場合は、Webコンポーネントのコンテンツを格納するフォルダとファイルを手動で作成します。

  3. 前のステップでの選択に応じて次のいずれかのタスクを実行し、Webコンポーネントを作成します。
    • Oracle JET CLIを使用してアプリケーションを作成した場合は、アプリケーションの最上位ディレクトリのターミナル・プロンプトで、次のコマンドを入力してWebコンポーネント・テンプレートを生成します:

      ojet create component component-name

      たとえば、JavaScriptで作成されたベース・アプリケーションにdemo-cardという名前のWebコンポーネントを作成するには、ojet create component demo-cardと入力します。このコマンドは、アプリケーションのjsフォルダにjet-composites/demo-cardを追加し、Webコンポーネントのスタブ・コンテンツを含むファイルを追加します。

      ベース・アプリケーションのJavaScriptまたはTypeScriptの実装により、Webコンポーネントのフォルダおよび実装が決まります。ベース・アプリケーションにTypeScript実装がある場合、jsフォルダではなくtsフォルダに、Webコンポーネントのスタブ・コンテンツが含まれます。

    • Oracle JET CLIを使用しない場合は、アプリケーションのjsフォルダまたはtsフォルダ内にjet-compositesフォルダを作成し、作成する各Webコンポーネントの名前を含むフォルダを追加します。

      demo-cardの例では、jet-compositesフォルダを作成し、そこにdemo-cardフォルダを追加します。残りのステップでは、個々のWebコンポーネント・ファイルを作成します。

  4. Webコンポーネントがサポートするプロパティ、メソッドおよびイベントを決定し、それらをWebコンポーネントのルート・フォルダ内のcomponent.jsonファイルに追加します(必要な場合はこのファイルを作成します)。
    Webコンポーネント・プロパティ、イベント・リスナーおよびメソッドの名前は、既存のHTML要素プロパティ、イベント・リスナーおよびメソッドと競合しないようにしてください。また、プロパティ名slotは使用しないでください。また、グローバル属性およびイベントを再定義しないでください。

    demo-cardの例では、Webコンポーネントのプロパティおよび連絡先のフル・ネーム、従業員の画像、役職、勤務先電話番号、電子メール・アドレスを定義しています。必須のプロパティは太字で強調表示されています。

     {
      "name": "demo-card",
      "description": "A card element that can display an avatar or initials on one side and employee information on the other.",
      "version": "1.0.2",
      "displayName": "Demo Card",
      "jetVersion": ">=6.0.0 <17.1.0",
       "properties": {
        "name": {
          "description": "The employee's full name.",
          "type": "string"
        },
        "avatar": {
          "description": "The url of the employee's image.",
          "type": "string"
        },
        "workTitle": {
          "description": "The employee's job title.",
          "type": "string"
        },
        "workNumber": {
          "description": "The employee's work number.",
          "type": "number"
        },
        "email": {
          "description": "The employee's email.",
          "type": "string"
        }
      }
    }
    

    この簡単なdemo-cardの例では、Webコンポーネントのプロパティのみを定義します。次に示すように、メソッドとイベントを定義するメタデータを追加することもできます。メタデータは、メソッドまたはイベントの名前のほか、サポートされているパラメータをリストします。

    {
      "properties": {
        ... contents omitted
      },
      "methods": {
         "flipCard": {
           "description": "Method to toggle flipping a card"
         },
         "enableFlip": {
           "description": "Enables or disables the ability to flip a card.",
           "params": [
             {
               "name": "bEnable",
               "description": "True to enable card flipping and false otherwise.",
               "type": "boolean"
              }
            ]
          },
        },
       "events": {
         "cardClick": {
           "description": "Triggered when a card is clicked and contains the value of the clicked card..",
           "bubbles": true,
           "detail": {
             "value": {
               "description": "The value of the card.",
               "type": "string"
                    }
                }
            } 
        }
    }    
  5. WebコンポーネントにViewModelが含まれる場合、その定義をWebコンポーネントのルート・フォルダのweb—component-name-viewModel.jsに追加します(必要な場合はこのファイルを作成します)。

    次のコード・サンプルは、demo-card WebコンポーネントのViewModelを示しています。コメントは、各関数の目的、パラメータおよび戻り値の説明です。

    define(['knockout', 'ojs/ojknockout'],
    	function(ko) {
    		function model(context) {
    			var self = this;
    			self.initials = null;
    			self.workFormatted = null;
    			var element = context.element;
    
    			/**
    			 * Formats a 10 digit number as a phone number.
    			 * @param  {number} number The number to format
    			 * @return {string}        The formatted phone number
    			 */
    			var formatPhoneNumber = function(number) {
    				return Number(number).toString().replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
    			}
    
    			if (context.properties.name) {
    				var initials = context.properties.name.match(/\b\w/g);
    				self.initials = (initials.shift() + initials.pop()).toUpperCase();
    			}
    			if (context.properties.workNumber)
    				self.workFormatted = formatPhoneNumber(context.properties.workNumber);
    
    			/**
    			 * Flips a card
    			 * @param  {MouseEvent} event The click event
    			 */
    			self.flipCard = function(event) {
    				if (event.type === 'click' || (event.type === 'keypress' && event.keyCode === 13)) {
    					// It's better to look for View elements using a selector 
    					// instead of by DOM node order which isn't guaranteed.
    					$(element).children('.demo-card-flip-container').toggleClass('demo-card-flipped');
    				}
    			};
    		}
    
    		return model;
    	}
    )
  6. Webコンポーネントのルート・フォルダで、View定義をweb—component-name-view.htmlに追加します(必要な場合はこのファイルを作成します)。

    demo-card WebコンポーネントのViewを次に示します。コンポーネントのメタデータに定義されたプロパティには、Viewバインディング・コンテキストの$propertiesプロパティを使用してアクセスします。

    
    <div tabindex="0" role="group" class="demo-card-flip-container"
      on-click="[[flipCard]]" on-keypress="[[flipCard]]" :aria-label="[[$properties.name + ' Press Enter for 
    more info.']]">
      <div class="demo-card-front-side">
        <oj-avatar class="demo-card-avatar" role="img" size="lg" initials="[[initials]]" 
    src="[[$properties.avatar]]" :aria-label="[['Avatar of ' + $properties.name]]">
        </oj-avatar>
        <h2>
          <oj-bind-text value="[[$properties.name]]"></oj-bind-text>
        </h2>
      </div>
    
      <div class="demo-card-back-side">
        <div class="demo-card-inner-back-side">
          <h2>
    			  <oj-bind-text value="[[$properties.name]]"></oj-bind-text>
          </h2>
          <h5>
            <oj-bind-text value="[[$properties.workTitle]]"></oj-bind-text>
          </h5>
          <oj-bind-if test="[[$properties.workNumber != null]]">
            <h5>Work</h5>
            <span class="demo-card-text"><oj-bind-text value="[[workFormatted]]"></oj-bind-text></span>
          </oj-bind-if>
          <oj-bind-if test="[[$properties.email != null]]">
            <h5>Email</h5>
            <span class="demo-card-text"><oj-bind-text value="[[$properties.email]]"></oj-bind-text></span>
          </oj-bind-if>
        </div>
      </div>
    </div>
    

    アクセシビリティのため、Viewのロールはgroupとして定義され、連絡先の名前にaria-labelが指定されています。通常、アプリケーション内で使用するWebコンポーネントViewのマークアップについては、同じアクセシビリティ・ガイドラインに従います。

  7. Oracle JET CLIを使用しない場合は、loader.js RequireJSモジュールを作成し、それをWebコンポーネントのルート・フォルダに配置します。

    loader.jsモジュールは、Webコンポーネントの依存性を定義し、コンポーネントのtagName (この例ではdemo-card)を登録します。

    define(['ojs/ojcomposite', 'text!./demo-card-view.html', './demo-card-viewModel',
            'text!./component.json', 'css!./demo-card-styles'],
      function(Composite, view, viewModel, metadata) {
        Composite.register('demo-card', {
          view: view, 
          viewModel: viewModel, 
          metadata: JSON.parse(metadata)
        });
      }
    );

    この例では、RequireJSプラグイン(css!./demo-card-styles)を介してCSSがロードされるため、それを明示的にComposite.register()に渡す必要はありません。

  8. Webコンポーネントで使用されるカスタム・スタイルを構成します。
    • スタイルが2、3個しかない場合は、それらをWebコンポーネントのルート・フォルダにあるweb—component-name-styles.cssに追加します(必要な場合はこのファイルを作成します)。

      たとえば、demo-card Webコンポーネントでは、デモ・カードの表示、幅、高さ、マージン、パディングなどのスタイルが定義されます。ユーザーが連絡先カードをクリックしたときに使用されるクラスも定義しています。CSSの一部を次に示します。

      /* This is to prevent the flash of unstyled content before the Web Component properties have been setup. */
      demo-card:not(.oj-complete) {
        visibility: hidden;
      }
      
      demo-card {
        display: block;
        width: 200px;
        height: 200px;
        perspective: 800px;
        margin: 10px;
        box-sizing: border-box;
        cursor: pointer;
      }
      
      demo-card h2,
      demo-card h5,
      demo-card a, 
      demo-card .demo-card-avatar  {
        color: #fff;
        padding: 0;
      }
       ... remaining contents omitted
      
      
    • Oracle JETツールを使用してアプリケーションを作成し、Sassを使用してCSSを生成する場合:
      1. 必要に応じて、アプリケーションの最上位ディレクトリのターミナル・プロンプトで、次のコマンドを入力し、node-sassをアプリケーションに追加します: ojet add sass

      2. web—component-name-styles.scssを作成し、Webコンポーネントの最上位レベルのフォルダ内に置きます。

      3. web—component-name-styles.scssを有効なSCSS構文で編集し、ファイルを保存します。

        この例では、変数でデモ・カードのサイズが定義されます。
        $demo-card-size: 200px;
        
        /* This is to prevent the flash of unstyled content before the Web Component properties have been setup. */
        demo-card:not(.oj-complete) {
          visibility: hidden;
        }
        
        demo-card {
          display: block;
          width: $demo-card-size;
          height: $demo-card-size;
          perspective: 800px;
          margin: 10px;
          box-sizing: border-box;
          cursor: pointer;
        }
        
        demo-card h2,
        demo-card h5,
        demo-card a,
        demo-card .demo-card-avatar  {
          color: #fff;
          padding: 0;
        }
        ... remaining contents omitted
        
      4. Sassをコンパイルするには、ターミナル・プロンプトでojet buildまたはojet serveを、--sassフラグおよびアプリケーション固有のオプションとともに入力します。

        ojet build|serve [options] --sass

        ojet build --sassでアプリケーションがコンパイルされ、web—component-name-styles.cssおよびweb—component-name-styles.css.mapファイルがデフォルト・プラットフォームのフォルダ内に生成されます。Webアプリケーションの場合は、コマンドによりweb/js/js-composites/web—component-name内にCSSが配置されます。

        ojet serve --sassでもアプリケーションがコンパイルされますが、Webアプリケーションがlivereloadが有効な実行中のブラウザに表示されます。アプリケーションのsrc/js/jet-composites/web—component-nameフォルダのweb—component-name-styles.scssへの変更を保存すると、Oracle JETはSassを再度コンパイルし、表示をリフレッシュします。

        ヒント:

        ojetコマンド構文のヘルプを表示するには、ターミナル・プロンプトでojet helpと入力します。
  9. Webコンポーネントのドキュメントを追加する場合は、Webコンポーネントのルート・フォルダにあるREADME.mdにコンテンツを追加します(必要な場合はこのファイルを作成します)。

    README.mdファイルには、コンポーネントの概要と適切に書式設定された例を含めるようにしてください。コンポーネントのコンシューマに提供する追加情報があれば、それも含めます。READMEファイル形式の推奨される標準は、Markdownです。

markdownについては、GitHubのドキュメントを参照してください。

demo-card WebコンポーネントCSSスタイルの完全なコードは、Webコンポーネントの基礎に関する項のクックブック・サンプルにあるdemo-card-styles.cssを参照してください。

メソッドとイベントを定義するWebコンポーネント・メタデータの追加の詳細は、Webコンポーネントのイベントに関する項のクックブック・サンプルを参照してください。

JETパックの作成

コンシューマが選んだコンポーネントが1つ以上のコンポーネントに関連する可能性がある場合、JETパックを作成するとプロジェクト管理が単純化されます。個々のJETパックで、特定のバージョンの参照コンポーネントが必要になることがあります。

基本的に、JETパックは関連するWebコンポーネントのライブラリです。それらのアセットが直接含まれるわけではなく、コンポーネントの特定バージョン・ストライプの索引として存在します。

ノート:

関連するコンポーネントの参照メカニズムとしてのパックには例外が1つあります。パックには、1つ以上のRequireJSバンドル・ファイルを含めることができます。これは、最適化された形式のコンポーネント・セットを、少数の物理的ダウンロードにパッケージ化したものです。ただし、これは常に、Oracle Component Exchangeで独立エンティティとして提供される実際のコンポーネントと合せて使用されます。

JETパックで参照されるコンポーネントは一緒に使用するためのものであり、その使用方法は個別のコンポーネント・バージョンによって制限されます。したがって、作成するJETパックによって、各コンポーネントの特定のバージョンと、同じセット内の他のコンポーネントの特定の固定バージョンとの関係が結ばれます。つまり、JETパックそのものにバージョン・ストライプがあり、これによってユーザーがアプリケーションにインポートする特定のコンポーネントが決まります。個々のコンポーネントのバージョン番号は異なる可能性があるため、JETパックによって、コンシューマが自らのアプリケーションとパック全体のバージョン(パックに含まれる個別のコンポーネントではない)を関連付けることが保証されます。

JETパックのバージョン管理の詳細は、「バージョン採番の標準」を参照してください。

  1. アプリケーションのルート・フォルダからJETツールを使用してJETパックを作成します。
    ojet create pack my-pack

    パック名については慎重に検討してください。この名前がそのパック内のすべてのコンポーネントの接頭辞になるためです。

    ツールによってテンプレート・ファイルを含むフォルダ構造が追加され、ユーザーはこれを変更する必要があります:

    /(working folder)
      /src
        /js
          /jet-composites
            /my-pack
              component.json
  2. アプリケーションのルート・フォルダからJETツールを使用して、JETパックにバンドルするコンポーネントを作成します。指定するコンポーネント名は、パック内で一意である必要があります。
    ojet create component my-widget-1 --pack=my-pack 

    ツールによって、コンポーネント・フォルダ/my-widget-1my-packルート・フォルダにネストされます。新しいコンポーネント・ファイルはスタンドアロンWebコンポーネント用に作成されるファイルと似ています。

    /(working folder)
      /src
        /js
          /jet-composites
            /my-pack
              component.json
              /my-widget-1
                /resources
                  /nls
                    /root
                      my-widget-1-strings.js
                component.json
                loader.js
                README.md
                my-widget-1-viewModel.js
                my-widget-1-styles.css
                my-widget-1-view.html

    作成されたコンポーネント・ファイルについて、次の点に注意してください。

    • component.jsonによって、コンポーネントのnamemy-widget-1と指定されます。packmy-packに設定され、コンポーネントのアイデンティティが全面的に定義されます。
    • loader.jsによって、新しいコンポーネントのHTMLタグがmy-pack-my-widget-1と登録されます。これは、パック名とコンポーネント名を連結したコンポーネントの完全名です。別のコンポーネントのメタデータとの依存関係、またはHTMLで、このコンポーネントを参照する必要がある場合は、完全名を使用します。
  3. オプションで、「JETパックのリソース・コンポーネントの作成」に従って作成した任意のリソース・コンポーネントについて、コンポーネント用の独自のcomponent.jsonファイルを含む作業フォルダをパック・ファイル構造に追加します。

    ツールによって、コンポーネント・フォルダ/my-widget-1my-packルート・フォルダにネストされます。新しいコンポーネント・ファイルはスタンドアロンWebコンポーネント用に作成されるファイルと似ています。

    /(working folder)
      /src
        /js
          /jet-composites
            /my-pack
              component.json
              /my-widget-1
                /resources
                  /nls
                    /root
                      my-widget-1-strings.js
                component.json
                loader.js
                README.md
                my-widget-1-viewModel.js
                my-widget-1-styles.css
                my-widget-1-view.html 
              /my-resource-component-1
                component.json
                /converters
                  file1.js
                  ...
                /resources
                  /nls
                    /root
                      strings-file.js
                /validators
                  file1.js
                  ...
    
  4. オプションで、パックの対象コンポーネントで必要なバンドルを生成します。詳細は、https://requirejs.org WebサイトのRequireJSのドキュメントを参照してください。

    ヒント:

    RequireJSを使用して、パック・コンポーネントの最適化されたバンドルを作成できます。こうすると、実行時に利用側アプリケーションが各コンポーネントを別々にダウンロードするかわりに、複数のコンポーネントを含む1つのJavaScriptファイルをダウンロードできます。ほとんど常に一緒に使用されるコンポーネント・セットがある場合にはこの機能を使用することをお薦めします。必要に応じて使用可能なコンポーネントをグループ化するために、1つのパックに任意の数のバンドルを含める(またはまったく含めない)ことができます。パック内のすべてのコンポーネントをいずれかのバンドルに含める必要はないこと、および各コンポーネントは1つのバンドルにしか含められないことに注意してください。

  5. テキスト・エディタを使用し、パックのフォルダ・ルートのcomponent.jsonファイルを次のサンプルのように変更して、パックの依存関係とオプションのバンドルを指定します。追加するコンポーネントは、完全名と特定のバージョンによって関連付ける必要があります。
    {
        "name": "my-pack",
        "version": "1.0.0",
        "type": "pack",
        "displayName": "My JET Pack",
        "description": "An example JET Pack",
        "dependencies": {
          "my-pack-my-widget-1":"1.0.0",
          ...
        },
        "bundles":{
            "my-pack/my-bundle":[
              "my-pack/my-bundle-file1/loader",
              ...
            ]
          },
        "extension": {
            "catalog": {
                "coverImage": "coverimage.png"
            }
         }
      }
    }

    パック・コンポーネントのcomponent.jsonファイルには、次の一意の定義を含める必要があります。

    • nameは、一意にする必要があるJETパックの名前です。グループに関連するネームスペースを使用して定義してください。パック内の個々のコンポーネントの完全名を作成するときに、この名前が前に付加されます。
    • versionには、SemVer範囲ではなく、パックの正確なバージョン番号を定義します。

      ノート:

      パックの所定のリリースにおけるバージョン番号の変更は、パック内容の最も大きな変更を示すものです。たとえば、パックに2つのコンポーネントが含まれているとき、あるリリースで、コンポーネントの1つはPatchレベルが変更され、もう1つはMajorバージョンが変更されると、パックのバージョン番号の変更でもMajorバージョンを変更する必要があります。パックの実際のバージョン番号が、参照しているコンポーネントいずれかのバージョン番号と一致しなくてはならないという要件はありません。詳細は、「バージョン採番の標準」を参照してください。

    • typepackに設定する必要があります。
    • displayNameは、Oracle Component Exchangeに表示されるパック・コンポーネントの名前です。これには読みやすく長すぎないものを設定します。
    • descriptionはOracle Component Exchangeに表示される説明です。たとえば、これを使用してパックの用途を説明します。
    • dependenciesには、コンポーネントの完全名(パック名とコンポーネント名を連結したもの)を指定して、パックを構成するコンポーネントのセットを定義します。ここでは、SemVer範囲ではなく、正確なバージョン番号を使用することに注意してください。依存関係のバージョン番号のリビジョンを管理して、参照コンポーネントのバージョンの変化を反映し、パック内でコンポーネントにアクセスするためのパスの一部も指定することが重要です。

      JETパック・ディレクトリにすべてのコンポーネントを含める場合は、パック内のすべてのコンポーネントに対して個別のエントリを定義するのではなく、dependenciesの値としてトークン"@dependencies@"を使用します。次のスニペットは、このトークンをcomponent.jsonファイルで使用する方法を示しています:

      {
        "name": "my-pack",
        "version": "1.0.0",
        "type": "pack",
        "displayName": "My JET Pack",
        "description": "An example JET Pack",
        "dependencies": "@dependencies@"
      }
    • bundlesには、使用可能なバンドル(オプション)と各バンドルの内容を定義します。バンドル名とそのバンドルの内容の両方を定義するときに、パック名接頭辞を使用することに注意してください。これは、それらのアーティファクトにマップするために必要なRequireJSパスであるためです。
    • catalogには、Oracle Component Exchangeの作業メタデータを定義します。このケースではカバー・イメージが含まれます。
  6. テキスト・エディタを使用し、コンポーネントのフォルダ・ルートのcomponent.jsonファイルを次のサンプルのように変更して、パックの関係を指定します。コンポーネントは、一意の名前(パック接頭辞なし)と特定のバージョンで識別する必要があります。
    {
        "name": "my-widget-1",
        "pack": "my-pack",
        "displayName": "My Web Component",
        "description": "Fully featured component",
        "version": "1.0.0",
        "jetVersion": "^10.0.0",
        "dependencies": {
          "my-widget-file1":"^1.0.0",
          ...
        },
        ...
    }

    パック・コンポーネントのcomponent.jsonファイルには、次の一意の定義を含める必要があります。

    • nameは、一意にする必要があるコンポーネントの名前です。この名前の前にパック名を付けると、コンポーネントの完全名になります。たとえば、
    • packは、コンポーネントが含まれるJETパックの名前です。
    • displayNameは、Oracle Component Exchangeに表示されるコンポーネントの名前です。
    • descriptionはOracle Component Exchangeに表示される説明です。たとえば、パック内のコンポーネントの役割(使用目的)を説明するために使用します。
    • versionには、SemVer範囲ではなく、コンポーネントの正確なバージョン番号を定義します。

    • jetVersionには、セマンティック・バージョン(SemVer)範囲を指定して、Oracle JETの互換性があるバージョン(1つまたは複数)を定義します。このバージョン番号のリビジョンを管理して、所定の変更の互換性をコンシューマに通知し、パック内でコンポーネントにアクセスするためのパスの一部も指定することが重要です。詳細は、「バージョン採番の標準」を参照してください。

    • dependenciesには、パック内のコンポーネントを構成するライブラリと他のコンポーネントのセットを定義します。依存コンポーネントもJETパックのメンバーとしてリストされているこのケースでは、ここに完全名(パック名とコンポーネント名を連結したもの)でコンポーネントを指定します。たとえば、my-pack-my-componentです。SemVer範囲を使用できることに注意してください。特定のJETパック・バージョン内のコンポーネントのために選択した範囲が、そのストライプのメンバーと重複していることが重要です。
  7. オプションで、作業フォルダのルートにreadmeファイルを作成します。これは、README.txt (またはマークダウン形式を使用するときはREADME.md)という名前のプレーン・テキスト・ファイルとして定義する必要があります。
  8. オプションで、Oracle Exchangeでコンポーネントを表示するためのカバー・イメージを作業フォルダのルートに作成します。ファイル名は、component.jsonファイルのname属性と同じにすることができます。
  9. コンポーネントをOracle Component Exchangeにアップロードしようとする場合は、「Webコンポーネントのパッケージ化」の説明に従い、JETツールを使用してJETパックの作業フォルダのzipアーカイブを作成します。
  10. 「Oracle Component ExchangeへのWebコンポーネントの公開」の説明に従い、コンポーネントをOracle Component Exchangeにアップロードすることで、Oracle Visual BuilderプロジェクトでのJETパックの使用をサポートします。

JETパックのリソース・コンポーネントの作成

JETパックにアセンブルするWebコンポーネント全体でアセットを再利用する場合は、リソース・コンポーネントを作成します。リソース・コンポーネントは、複数のJETパックで再利用できます。

複雑なコンポーネントのセットを扱うときは、複数のコンポーネント間で特定のアセットを共有できると役立つことがあります。そのような場合、コンポーネントすべてを1つのJETパックに含めて、共有アセットを保持するためにリソース・コンポーネントをパックに追加できます。パックに格納できる内容に制限はありません。通常、共有されるJavaScript、CSS、JSONのファイルとイメージが公開されます。通常、サードパーティ・ライブラリは参照コンポーネントから参照する必要があることに注意してください。リソース・コンポーネントには組み込まないでください。

リソース・コンポーネントを作成するためにツールは必要ありません。便利な場所にフォルダを作成する必要があります。最終的にはこのフォルダを圧縮して、配布可能なリソース・コンポーネントを作成します。このフォルダの内部には、望みの構造で任意のコンテンツを含めることができます。

リソース・コンポーネントを作成するには:

  1. まだ作成していない場合は、アプリケーションのルート・フォルダから次のコマンドを使用して、リソース・コンポーネントを含めるJETパックを作成します:

    ojet create pack my-resource-pack

  2. 引き続きアプリケーションのルート・フォルダから、JETパックにリソース・コンポーネントを作成します:

    ojet create component my-resource-comp --type=resource --pack=my-resource-pack

    ツールによって、1つのテンプレートcomponent.jsonファイルおよび索引ファイルを含むフォルダ構造が追加されます。

    /root folder
      /src
        /js or /ts
          /jet-composites
            /my-resource-pack
    	    /my-resource-comp
    	       component.json
  3. 作成したフォルダ(この例ではmy-resource-comp)に必要なコンテンツを移入します。変換バンドルのNLSコンテンツを除き、望みの構造でコンテンツを追加できます。NLSコンテンツのケースでは、通常のJETフォルダ構造を維持します。リソース・コンポーネントにそのようなバンドルを含まれる場合に重要です。
    /(my-resource-folder)
      /converters
        phoneConverter.js
        phoneConverterFactory.js
      /resources
        /nls
          /root
           oj-ext-strings.js
        /phone
          countryCodes.json
      /validators
        emailValidator.js
        emailValidatorFactory.js
        phoneValidator.js
        phoneValidatorFactory.js
        urlValidator.js
        urlValidatorFactory.js
    

    このサンプルでは、翻訳バンドルの/resources/nlsフォルダ構造は、JETツールによって生成されるアプリケーションのフォルダ構想に基づいて保たれることに注意してください。

  4. テキスト・エディタを使用して、次のサンプルのようなフォルダ・ルートにある、JETパックmy-resource-packのリソースmy-resource-compを定義するcomponent.jsonファイルを更新します。
    {
      "name": "my-resource-comp",
      "pack": "my-resource-pack",
      "displayName": "Oracle Jet Extended Utilities",
      "description": "A set of reusable utility classes used by the Oracle JET extended 
                      component set and available for general use.  Includes various 
                      reusable validators",
      "license": "https://opensource.org/licenses/UPL",
      "type": "resource",
      "version": "2.0.2",
      "jetVersion": ">=8.0.0 <10.1.0",
      "publicModules": [
        "validators/emailValidatorFactory",
        "validators/urlValidatorFactory"
      ],
      "extension":{
        "catalog": {
          "category": "Resources",
            "coverImage": "cca-resource-folder.svg"
        }
      }
    }

    リソース・コンポーネントのcomponent.jsonファイルには、次の一意の定義を含める必要があります。

    • nameは、一意にする必要があるリソース・コンポーネントの名前です。グループに関連するネームスペースを使用して定義してください。
    • packは、リソース・コンポーネントが含まれるJETパックの名前です。
    • displayNameは、Oracle Component Exchangeに表示されるリソース・コンポーネントの名前です。これには読みやすく長すぎないものを設定します。
    • descriptionはOracle Component Exchangeに表示される説明です。たとえば、これを使用して、コンポーネントによって提供される使用可能なアセットを説明します。
    • typeresourceに設定する必要があります。
    • versionには、リソース・コンポーネントのセマンティック・バージョン(SemVer)全体を定義します。このバージョン番号のリビジョンを管理して、所定の変更の互換性をコンシューマに通知することが重要です。

      ノート:

      リソース・コンポーネント・バージョンの変更は、リソース・コンポーネント内のすべての変更をロールアップする必要があり、.jsファイルのみの変更に限定されないことがあります。共有の.cssファイルに定義されたCSSセレクタに対する変更によって、ダウンストリームでのセレクタの使用方法をユーザーが変更せざるを得ない場合は、メジャー・バージョンの変更がトリガーされることがあります。詳細は、「バージョン採番の標準」を参照してください。

    • jetVersionには、サポートされるOracle JETバージョン範囲をSemVer表記を使用して定義します。これはオプションです。リソース・コンポーネントに含めるものの性質によって異なります。コンポーネントにJavaScriptコードが含まれ、そのコードでOracle JET APIが参照される場合、そのケースのJETバージョンの範囲を実際に組み込む必要があります。セマンティック・バージョンの指定方法の詳細は、「バージョン採番の標準」を参照してください。
    • publicModulesには、リソース・コンポーネント内のエントリ・ポイントのリストを指定します。これらのエントリ・ポイントはパブリックと見なされ、このコンポーネントに依存するすべてのコンポーネントによって使用されると想定されます。配列に指定されないすべてのAPIは、パック内のプライベートと見なされ、外部では使用できず、同じパック・ネームスペース内のコンポーネントによってしか使用できません。
    • catalogには、Oracle Component Exchangeの作業メタデータを定義します。このケースではカバー・イメージが含まれます。
  5. オプションで、作業フォルダのルートにreadmeファイルを作成します。readmeはリソースのアセットを記述するために使用できます。これは、README.txt (またはマークダウン形式を使用するときはREADME.md)という名前のプレーン・テキスト・ファイルとして定義する必要があります。

    ヒント:

    アセットの状態を説明するときは注意してください。たとえば、パブリックとみなし、外部コンシューマ(コンポーネントが所属するJETパック外部のコードなど)が安全に使用できるユーティリティ・クラスは、リソース・コンポーネントに組み込むことを選択できます。ただし、他のアセットはパック内でプライベートであると記述することをお薦めします。

  6. オプションで、作業フォルダのルートに変更ログ・ファイルを作成します。変更ログには、パックの重要な変更の詳細が経時的に記録されます。作成することを強くお薦めします。これは、CHANGELOG.txt (またはマークダウン形式を使用するときはCHANGELOG.md)という名前のテキスト・ファイルとして定義する必要があります。
  7. オプションで、作業フォルダのルートにライセンス・ファイルを作成します。
  8. オプションで、Oracle Exchangeでコンポーネントを表示するためのカバー・イメージを作業フォルダのルートに作成します。サードパーティのロゴを使用すると、ここで使用方法を示すのに役立ちます。ファイル名は、component.jsonファイルのname属性と同じにすることができます。
  9. コンポーネントをOracle Component Exchangeにアップロードするときは、作業フォルダのzipアーカイブを作成します。アーカイブ・ファイル名では<fullName>-<version>.zipという形式を使用することをお薦めします。たとえば、my-resource-pack-my-resource-comp-2.0.2.zipです。
JETパックでリソース・コンポーネントを使用する方法の詳細は、「JETパックの作成」を参照してください。

Webコンポーネントの参照コンポーネントの作成

Webコンポーネントで使用するためにサードパーティ・ライブラリへのポインタを取得する必要があるときは、参照コンポーネントを作成します。

場合によっては、JET Webコンポーネントが機能するためにサードパーティ・ライブラリを使用する必要があります。それらのライブラリをコンポーネントそのものまたはリソース・コンポーネントに埋め込むことは可能ですが、通常は参照コンポーネントを定義してライブラリの共有コピーを参照することをお薦めします。

参照コンポーネントの作成

参照コンポーネントを作成するためにツールは必要ありません。便利な場所にフォルダを作成して、そこでcomponent.jsonファイルの参照コンポーネントのメタデータを定義する必要があります。最終的にはこのフォルダを圧縮して、配布可能な参照コンポーネントを作成します。

参照コンポーネントは通常はスタンドアロンであるため、作成するcomponent.jsonファイルをJETパックに含めないでください。

参照コンポーネントを作成するには:

  1. 作業フォルダを作成し、そのフォルダのルートに、次のサンプルに似たcomponent.jsonファイルをテキスト・エディタを使用して作成します。このファイルでmoment.jsライブラリを参照します。
    {
      "name": "oj-ref-moment",
      "displayName": "Moment library",
      "description": "Supplies reference information for moment.js used to parse, 
                      validate, manipulate, and display dates and times in JavaScript",
      "license": "https://opensource.org/licenses/MIT",
      "type": "reference",
      "package":"moment",
      "version": "2.24.0",
      "paths": {
        "npm": {
          "debug": "moment",
          "min": "min/moment.min"
        },
        "cdn": {
          "debug": "https://static.oracle.com/cdn/jet/packs/3rdparty/moment/2.24.0/moment.min",
          "min": "https://static.oracle.com/cdn/jet/packs/3rdparty/moment/2.24.0/moment.min"
        }
      },
      "extension": {
        "catalog": {
          "category": "Third Party",
          "tags": [
            "momentjs"
          ],
          "coverImage": "coverImage.png"
        }
      }
    }

    参照コンポーネントのcomponent.jsonファイルには、次の一意の定義を含める必要があります。

    • nameは、一意にする必要がある参照コンポーネントの名前です。グループに関連するネームスペースを使用して定義してください。
    • displayNameは、Oracle Component Exchangeに表示されるリソース・コンポーネントの名前です。これには読みやすく長すぎないものを設定します。
    • descriptionはOracle Component Exchangeに表示される説明です。たとえば、これを使用してサードパーティ・ライブラリの機能を説明します。
    • licenseには、サードパーティ・ライブラリのライセンスを指定する必要があります。
    • typereferenceに設定する必要があります。
    • packageには、ライブラリのnpmパッケージ名を定義します。これは関連するRequireJSパス(ライブラリを指す)の名前としても使用され、この参照に依存するコンポーネントによっても使用されます。
    • versionには、この参照コンポーネントで定義するサードパーティ・ライブラリのバージョンを指定する必要があります。所定のライブラリの複数のバージョンを参照する必要がある場合、それぞれにマップするために複数のバージョンの参照コンポーネントが必要になります。
    • pathsには、このライブラリのCDN位置を定義します。Oracle CDNへのアクセスの詳細は、次を参照してください。
    • minには、使用するライブラリの最適なバージョンを指定します。デバッグ・パスには、デバッグ・バージョンを指定することも、ここに示す縮小バージョンを指定することもできます。
    • catalogには、Oracle Component Exchangeの作業メタデータを定義します。このケースではカバー・イメージが含まれます。
  2. オプションで、作業フォルダのルートにreadmeファイルを作成します。readmeは、参照用のサードパーティ・コンポーネントWebサイトを示すために使用できます。これは、README.txt (またはマークダウン形式を使用するときはREADME.md)という名前のプレーン・テキスト・ファイルとして定義する必要があります。
  3. オプションで、Oracle Exchangeでコンポーネントを表示するためのカバー・イメージを作業フォルダのルートに作成します。サードパーティのロゴを使用すると、ここで使用方法を示すのに役立ちます。ファイル名は、component.jsonファイルのname属性と同じにすることができます。
  4. コンポーネントをOracle Component Exchangeにアップロードするときは、作業フォルダのzipアーカイブを作成します。アーカイブ・ファイル名では<fullName>-<version>.zipという形式を使用することをお薦めします。たとえば、oj-ref-moment-2.24.0.zipです。
  5. コンポーネントをCDNにアップロードすることで、Oracle Visual Builderプロジェクトでの参照コンポーネントの使用をサポートします。詳細は、後述の説明を参照してください。

参照コンポーネントの使用

Webコンポーネントが、これらの参照コンポーネントのいずれかに定義されたサードパーティ・ライブラリにアクセスする必要があるときは、component.jsonのdependency属性のメタデータを使用して、参照コンポーネントの明示的なバージョンを示すか、セマンティック範囲を指定します。ここで示すのは、特定のバージョンの2つの参照コンポーネントを使用するコンポーネントの単純な例です。

{
    "name":"calendar",
    "pack":"oj-sample",
    "displayName": "JET Calendar",
    "description": "FullCalendar wrapper with Accessibility added.",
    "version": "1.0.2",
    "jetVersion": "^9.0.0",
    "dependencies": {
        "oj-ref-moment":"2.24.0",
        "oj-ref-fullcalendar":"3.9.0"
    },
 
    ...

前述のコンポーネントがOracle JETまたはOracle Visual Builderプロジェクトに追加されるとき、この依存関係情報が使用されて、参照コンポーネントとしてポイントされるサードパーティ・ライブラリの正しいRequireJSパスが作成されます。

セマンティック・バージョンの使用方法の詳細は、「バージョン採番の標準」を参照してください。

または、参照コンポーネントに依存するWebコンポーネントをインストールし、Oracle JET CLIを使用すると、ツールによって自動的にnpmインストールが実行され、ライブラリがローカルになります。ただし、同じコンポーネントがOracle Visual Builderで使用されるときは、CDN位置を使用する必要があります。つまり、参照コンポーネントはVisual Builderで使用できるようにCDNに存在する必要があります。

Webコンポーネントのテーマ適用

Oracle JET Webコンポーネントでは、背景色など、色スタイルのテーマを適用可能な利用側アプリケーションからスタイルを継承する必要がある場合があります。Webコンポーネントでテーマ適用を有効にして、利用側アプリケーションで指定されたスタイルをカスタマイズできるようにすることもできます。テーマ適用サポートをWebコンポーネントに追加し、CSS変数を定義してコンポーネントのルック・アンド・フィールのカスタマイズをサポートできます。

Webコンポーネントのテーマ適用について

Webコンポーネントにテーマを適用する場合、SASS部分ファイルを使用してスタイル・クラスを定義し、JETツールを使用して最適化されたCSSを導出することで、CSS変数を介してスタイルを公開します。

作成するカスタム・コンポーネントおよびコンポーネント・パックにテーマを適用することは必ず必要なわけではありません。多くの場合、カスタム・テーマを有効にする必要はありません。たとえば、追加のユーザー・インタフェースを使用せずに一部のコアJETコンポーネントのみをラップする必要がある場合、テーマ適用は必要ありません。この2つのユースケースが示すように、利用側アプリケーションでコンポーネントがどのように使用されるかによって異なります。

  • コンポーネントで色スタイルがテーマ適用可能である必要がある背景色など、コンポーネントが利用側アプリケーションからスタイルを継承する必要がある場合は、カスタム・コンポーネントまたはコンポーネント・パックをテーマ対応にします。

  • コンポーネントが独自のスタイル・クラスを定義し、そのスタイルをカスタマイズのために利用側アプリケーションでテーマ適用可能にする必要がある場合は、カスタム・コンポーネントまたはコンポーネント・パックをテーマ対応にします。

Oracle JETは、アプリケーションのテーマ適用でCSS変数に依存します。CSS変数を使用したWebコンポーネントのテーマ適用では、利用側アプリケーションへの容易な統合がサポートされています。テーマ適用プロセスを合理化し、最適化されたスタイルシートの生成をサポートするために、WebコンポーネントはSASS部分ファイルおよびSCSS処理に依存します。

Webコンポーネントを作成した後、ojet add themingコマンドを実行して、コンポーネントを追加するベース・アプリケーションにscss処理のサポートをインストールします。その後、ojet createコンポーネント・コマンドを使用して、コンポーネントをjet-compositesフォルダに追加できます。新しいコンポーネント・プロジェクトには、次のように、テーマ・フォルダと、SASS部分ファイルを含むbaseredwoodstableの3つのサブフォルダが含まれます:

  • baseフォルダ - テーマ間で共通のコンポーネントのスタイル・クラスを定義するベースSASS部分ファイルが含まれます。スタイル・クラスはCSS変数を参照し、その値は通常、テーマ固有のSASS部分ファイルによって提供されます。

  • redwoodフォルダ - Redwoodテーマのテーマ固有のSASS部分ファイルが含まれます。ここでは、コンポーネントのスタイル設定を定義します。具体的には、テーマのバリアントがベースの_myComponent.scss部分ファイルに設定する必要があるCSS変数値を設定するために使用します。RedwoodテーマはOracleアプリケーションのルック・アンド・フィールを実装し、Oracleの要件に対応するために将来の変更が行われます。

  • stableフォルダ - Stableテーマのテーマ固有のSASS部分ファイルが含まれます。ここでは、コンポーネントのスタイル設定を定義します。具体的には、テーマのバリアントがベースの_myComponent.scss部分ファイルに設定する必要があるCSS変数値を設定するために使用します。将来のテーマの更新がカスタム・テーマに影響を与える可能性を減らしたい場合は、カスタム・テーマのベース・テーマとしてStableテーマをお薦めします。

これらのフォルダ間で分割されたSASS部分は、コア・スタイル定義と変数駆動のテーマ固有の定義の分離をサポートしています。この構造を使用すると複数のテーマを定義できますが、実際には、Redwoodテーマがモバイル・デバイス上のiOSやデスクトップ・マシン上のWindowsなどのプラットフォームおよび環境にまたがって実行されるJET Webアプリケーションの要件ではありません。

生成されたテーマ・フォルダに加えて、各コンポーネントには、コンポーネント・フォルダのルートに、テーマSASS部分から最終CSSを生成するためにJETツールで処理されるSCSSファイル(myComponent-styles.SCSS)もあります。ルート.scssファイルには、次の単一行が含まれます。

@import "themes/redwood/_myComponent.scss";

Webコンポーネントのテーマ適用のガイドライン

JETでは、テーマ適用の主要手段としてCSS変数を使用しているため、サポートされている単一のテーマ構成でも、利用側アプリケーションのニーズに適応できます。

Webコンポーネントのテーマを適用する場合は、プロセスを導くための次の考慮事項に従ってください。

  • 目的は、ほとんどの場合、テーマが適用されたWebコンポーネントを即時利用可能な状態で動作させ、利用側アプリケーションにより引き続きそのコンポーネントにテーマを適用できるようにすることです。コンポーネント・セット全体で単一のデフォルト・テーマを維持します。
  • Webコンポーネントには、即時利用可能な状態で動作する単一のデフォルト・テーマを用意する必要がありますが、コンポーネント内で複数のテーマの設定を定義することもできます。直接実行時に使用するためにコンポーネントに対しアクティブにして表示できるのは、1つのテーマのみです。
  • サポートされているテーマをコンポーネントまたはパックのreadmeファイルにドキュメント化します。この情報は、component.jsonで指定するコンポーネント・メタデータと組み合せて、利用側アプリケーションが満たす必要がある規定を指定します。
  • CSS変数を使用して、テーマ内で構成可能にするものを外部化します。これにより、必要に応じてコンポーネント・インスタンス・スタイルのオーバーライドがサポートされ、コンポーネントのカスタム・テーマの作成も簡略化されます。
  • JET Redwoodのコア・テーマからできるだけ多くの情報(色ランプやサイズ設定など)を継承します。これにより、Webコンポーネントのテーマ適用がアプリケーションに存在するすべてのコアJETコンポーネントと調和し、コンポーネントがカスタム・テーマに適切に適応できるようになります。可能な場合は、JETまたは他のパブリック・レイアウト・スタイルによって提供されるoj-flexクラスを使用してレイアウトを管理します。これにより、パディングなどのテーマの細かい属性の一貫性が保証されます。
  • CSSの使用は、JETパック・レベルまたはアプリケーション・レベルで統合できるように最適化する必要があります。CSS変数を使用すると、CSS統合がサポートされます。

アプリケーションまたはインスタンス・レベルで利用側アプリケーションがオーバーライドできるように、テーマ適用されたコンポーネントがCSS変数を介して構成されている場合は、コンポーネントREADME.mdのThemingというセクションにこれらの変数を追加し、それらの動作と設定内容をドキュメント化します。この方法でドキュメント化されると、変数はコンポーネントAPIの正式な部分になり、変更を加える場合は通常のセマフォ・ルールに従う必要があります。デフォルト・テーマに対する変更は、セマンティック・バージョン番号のMAJORバージョン番号変更としてクラス化する必要があります。

Webコンポーネントのテーマ適用

Oracle JETツールを使用して、カスタムWebコンポーネント・プロジェクトをテーマ対応にし、CSS変数を使用して、プロジェクトに追加するカスタム・コンポーネントにテーマを適用できます。

JETツールを使用して、含まれているプロジェクトにテーマ適用サポートを追加することで、新しいWebコンポーネント・プロジェクトまたはJETパック・プロジェクトのテーマ適用を有効にします。このツールは、CSS生成プロセスを合理化するために使用されるSASS部分ファイルを追加し、ベース・テーマへの変更をサポートするカスタム・コンポーネントまたはパックを作成するための前提条件ステップです。

プロジェクト・ルートでojet add themingコマンドを実行して含まれているプロジェクトをテーマ対応にすると、プロジェクトで作成する新しいカスタム・コンポーネントには、themesフォルダと、それぞれに変更する単一のSASS部分ファイルが含まれるサブフォルダが含まれます:

  • /<componentName>/themes/base/_<componentName>.sccsは、テーマ間で共通のままにするコンポーネントのカスタム・スタイルを定義します。テーマのバリエーションを使用して変更する必要があるスタイル設定部分は、CSS変数値を介して挿入され、ベースJETテーマまたはコンポーネント・テーマ固有の設定から取得されます。
  • /<componentName>/themes/redwood/_<componentName>.sccsには、コンポーネントのテーマ固有の設定が含まれます。具体的には、このファイルで、Redwoodテーマに基づくカスタム・テーマが基本部分に設定する必要があるCSS変数値を指定できます。
  • /<componentName>/themes/stable/_<componentName>.sccsには、コンポーネントのテーマ固有の設定が含まれます。具体的には、このファイルで、Stableテーマに基づくカスタム・テーマが基本部分に設定する必要があるCSS変数値を指定できます。

また、テーマ対応プロジェクトのカスタム・コンポーネントにも、コンポーネントのルート・フォルダに<componentName>.scss SASSファイルが含まれます。このファイルは、JETビルド・プロセスがSASS部分ファイルから生成するCSSファイルをインポートするために使用されます。

ノート:

ojet add themingを実行する前にパックまたはコンポーネントを作成すると、CSSビルド・エラーが発生する場合があります。add themingコマンドを使用すると、SCSSコンパイルでCSSを生成できます。パックまたはコンポーネントを作成する前に、必ずadd themingを実行してください。

始める前に:

  • Webコンポーネントのカスタム・セレクタを直接定義する際に使用するCSS変数および値の概要は、JET APIリファレンス・ドキュメントのJET CSS変数を参照してください。
  • CSS変数の使用例については、Oracle JETクックブックのCSS変数を参照してください。
  • この対話形式のデモ・アプリケーションで使用可能なCSS変数について理解を深める場合は、必要に応じてCSS変数テーマ・ビルダー - 「指示」タブ・アプリケーションをダウンロードしてインストールします。CSS変数のオーバーライドによってデモ・ツールUIがどのように変化するかを学習するには、オンラインの指示に従ってテーマ定義ファイルを変更します。

テーマのサポートを追加し、コンポーネントにテーマを適用するには:

  1. ターミナル・プロンプトで、Webコンポーネント・プロジェクトの最上位ディレクトリから次のコマンドを入力し、テーマ・ツールチェーンをインストールします。
    ojet add theming
  2. 含まれているプロジェクトにWebコンポーネントを作成します。または、このサンプルに示すように、JETパックを作成し、Webコンポーネントをパックに追加します。
    ojet create pack my-pack
    ojet create component my-widget1 --pack=my-pack

    たとえば、次のコマンドでは、パックoj-sampleが作成され、カスタム・コンポーネントmetricがパックに追加されます。

    ojet create pack oj-sample
    ojet create component metric --pack=oj-sample

    これらのコマンドは、oj-sampleパック・フォルダおよびmetricコンポーネントを含むjet-compositesフォルダを作成します。

    src
    |   index.html
    |   
    +---css
    +---js
    \---ts
        +---jet-composites
        |   \---oj-sample
        |       |   component.json
        |       |   
        |       \---metric
        |           |   component.json
        |           |   loader.ts
        |           |   metric-styles.scss
        |           |   metric-view.html
        |           |   metric-viewModel.ts
        |           |   README.md
        |           |   
        |           +---resources
        |           \---themes
        |               +---base
        |               |       _metric.scss
        |               |       
        |               +---redwood
        |               |       _metric.scss
        |               |       
        |               \---stable
        |                       _metric.scss
        |                       
        +---viewModels
        +---views
    

    上のディレクトリでは、metricフォルダにベースSASSファイルmetric-styles.scssが表示されています。themesサブフォルダには、変更するSASS部分ファイル_metric.scssが含まれています。

    ノート:

    コンポーネントのルート・フォルダに.scssファイルのかわりに.cssファイルが表示される場合は、コンポーネントを作成する前にadd themingコマンドを実行していないことを示しています。

  3. /<componentName>/themes/baseフォルダで、_componentName.scss SAAS部分ファイルを編集して、コンポーネントのスタイル・セレクタを定義します。セレクタのプロパティは、ハードコードされた値を使用して定義することも、利用側アプリケーションによるプロパティのオーバーライドを許可する場合にCSS変数によって制御されるプロパティを定義することもできます。

    スタイル名と変数名は、再定義しないように、所有するコンポーネントのHTML要素タグに名前空間を指定しておく必要があります。たとえば、スタイル.oj-sample-metric-value-colorは、oj-sample-metricによって名前空間が指定されます。

    @import "oj/utilities/_oj.utilities.modules.scss";
    // Even if this file is imported many times 'module-include-once' ensures the content is included just once.
    @include module-include-once("oj-sample-metric.base") {
      oj-sample-metric:not(.oj-complete){
        visibility: hidden;
      }
      // Selector definitions section
      oj-sample-metric .oj-sample-metric-value-text {
        display:inline-block;
        align-self:center;
      }
      oj-sample-metric .oj-sample-metric-label {
        font-size: var(--oj-sample-metric-label-font-size);
      }
      oj-sample-metric .oj-sample-metric-value-color {
        color: var(--oj-sample-metric-value-color);
      }
      oj-sample-metric .oj-sample-metric-label-color {
        color: var(--oj-sample-metric-label-color);
      }
      ...
    }

    このサンプルでは、セレクタ.oj-sample-metric-value-textセレクタのみがその場で完全に定義され、CSS変数を参照しません。このスタイルのプロパティはオーバーライドできません。.oj-sample-metric-labelセレクタのfont-sizeプロパティは、テーマ固有のSASS部分ファイルで定義するCSS変数を参照します。.oj-sample-metric-value-colorおよび.oj-sample-metric-label-colorセレクタのcolorプロパティも、定義するCSS変数を参照します。CSS変数を使用すると、利用側アプリケーションでこれらのプロパティをオーバーライドできます。

    利用側アプリケーションでセレクタ・プロパティ値のオーバーライドを許可する必要がない場合は、テーマ固有のSASS部分ファイルで定義しなくても、JET自体で定義された変数を参照できます。次のサンプルでは、セレクタは、テキストの色を定義するJET CSS変数である--oj-core-text-color-secondaryによって直接定義されます。

      ...
      oj-sample-metric .oj-sample-metric-label-color {
        color: var(--oj-core-text-color-secondary);
      }
      ...
    }

    JET CSS変数のリストは、このトピックの「始める前に」の項にリストされているリソースを参照してください。

    ノート:

    次のようなマッピングを定義するとします。

    color: rgb(var(--oj-palette-neutral-rgb-60));

    その後、プロジェクトをビルドすると、「エラー: 関数rgbに引数$greenがありません」というエラーが.scssファイルに表示されます。これはSASSコンパイラの既知の問題であり、回避策は次のように関数名に大文字を使用することです。

    color: RGB(var(--oj-palette-neutral-rgb-60));
  4. /<componentName>/themes/redwoodまたは/<componentName>/themes/stableフォルダで、_componentName.scss SAAS部分ファイルを編集して、基本部分SCCSファイルに必要なテーマ固有の設定を指定します。ルート内では、コンポーネント固有のすべてのCSS変数をハードコードされた値またはJET CSS変数として定義できます。
    @include module-include-once("_metric.redwood") {
      :root {
        --oj-sample-metric-label-font-size:0.875rem;
        --oj-sample-metric-value-color:var(--oj-core-text-color-primary);
        --oj-sample-metric-label-color:var(--oj-core-text-color-secondary);
        ...
      }
    }

    このサンプルでは、CSS変数--oj-sample-metric-label-font-sizeのみがハードコードされています。その他の2つの変数は、基礎となるJET変数から値を継承します。ただし、Webコンポーネントを使用するアプリケーションでは、テーマ部分ファイルに定義されているすべての設定がオーバーライドされる場合があります。

    JET CSS変数のリストは、このトピックの「始める前に」の項にリストされているリソースを参照してください。

    利用側アプリケーション用にテーマ適用されたコンポーネントまたはパックを準備するには、次のトピックを参照してください:

JETパックのCSSの統合

JETパック内のカスタム・コンポーネントのスタイルシートを単一のCSSファイルに統合できます。

カスタムWebコンポーネントをJETパックに追加すると、最初は各コンポーネントに独自のCSSファイルが用意されます。このアプローチは機能しますが、本番アプリケーションでは、サーバーへの物理的なラウンドトリップ回数を減らし、ブラウザ・キャッシュとCDNを最大限に活用することが最適です。ラウンドトリップ数を減らすには、パックに追加する共有リソース・コンポーネントを使用して、単一のCSSファイルからのロードを有効にします。

始める前に:

パックに単一の共有CSSファイルを作成するには:

  1. component.jsonファイルで作成したリソース・コンポーネントをパック・ファイル構造に追加し、パック内の個々のコンポーネントのCSSのインポートに使用する単一のSCSSファイルを含むサブフォルダstylesを追加します。

    上の図では、フォルダcommonはリソース・コンポーネントの作業フォルダで、stylesサブフォルダにはパックに対応する名前のSCSSファイルoj-sample-style.scssが表示されています。

  2. stylesフォルダのSCCSファイルを編集して、統合スタイルシートに結合するコンポーネントのSCSS部分ファイルのインポート・コマンドをレプリケートします。
    @import "../../metric/themes/redwood/_metric.scss";
    @import "../../input-email/themes/redwood/_input-email.scss";
    @import "../../input-email/themes/redwood/_input-url.scss";

    このサンプルでは、oj-sampleパックの例の3つのコンポーネントのimport文を示します。metricコンポーネントのインポートに加えて、input-emailコンポーネントおよびinput-urlコンポーネント(図では省略)のimport文を含めます。

  3. 共有スタイルシートに統合するコンポーネントごとに、コンポーネントのloader.jsファイル(TypeScriptプロジェクトの場合は.ts)を編集して、リソース・コンポーネントで指定された共有スタイルシートを参照します。コンポーネント固有のスタイルシートを引き続き使用するコンポーネントのローダー・ファイルは編集しないでください。
    define (['ojs/ojcomposite',
             'text!./metric-view.html',
             './metric-viewModel',
             'text!./component.json',
             'css!oj-sample/common/styles/oj-sample-styles'
             ],
     
    function(Composite, view, viewModel, metadata){
      Composite.register("oj-sample-metric", {
        view: view,
        viewModel: viewModel,
        metadata: JSON.parse(metadata)
      });
     }
    );

    このJavaScriptサンプルでは、metricコンポーネントのローダー・スクリプトは、リソース・コンポーネントの/common/stylesフォルダに追加されたSCSSファイルの変更されたパス文参照oj-sample-styleを示しています。

    TypeScriptアプリケーションの場合は、次のサンプルのようにimport文を変更します:

    import "css!oj-sample/common/styles/oj-sample-styles";

    ノート:

    パック・コンポーネントの参照に相対パス・マッピングを使用しないでください。JavaScriptおよびTypeScriptアプリケーションに関する前の例に示されているように、パック・コンポーネントの統合ファイルへのパスを識別します。

    利用側アプリケーションがスタイルを独自のCSSで完全に管理できるように、さらに最適化を実行するには、次のタスクを実行します:

利用側アプリケーションでスタイルを提供できるようにCSSを最適化

利用側アプリケーションのテーマCSSのコンポーネント・スタイルのロードを最適化できます。

テーマを適用したコンポーネントのダウンストリーム使用をサポートするには、Webコンポーネントでコンポーネントに必要な規約を確立する必要があります。テーマを適用したカスタム・コンポーネントをアプリケーションに使用する開発者は、スタイルを変更せずに組み込み、テーマ・スタイルを独自のスタイルでオーバーライドし、オプションでCSS最適化を実行して単一のCSSファイルからのロードを有効にできます。

これらの使用を有効にするには、ダウンストリーム開発者がアプリケーションにコンポーネントを追加するときに従う規約を確立する必要があります。

規約を定義してサポートするには、コンポーネントが公開するテーマSCSS部分を指定するメタデータでカスタム・コンポーネントを装飾し、コンポーネントCSSのデフォルト・ローダー・スクリプトを変更して、構成可能なojcssプラグインでCSS requireJSプラグインを指定します。

始める前に:

  • JETパックのCSSの統合の説明に従って、パック・レベルで作成したリソース・コンポーネントを使用して、コンポーネント・スタイルシートの統合を設定します。

コンポーネントのテーマ使用規約を定義するには:

  1. 共有スタイルシートに統合するコンポーネントごとに、コンポーネントのloader.jsファイル(TypeScriptプロジェクトの場合は.ts)を編集し、通常のCSS requireJSプラグインを構成可能なojcssプラグインに置き換えて、統合スタイルシートのimport文を変更します。
    define (['ojs/ojcomposite',
             'text!./metric-view.html',
             './metric-viewModel',
             'text!./component.json',
             'ojcss!oj-sample/common/styles/oj-sample-styles'
             ],
     
    function(Composite, view, viewModel, metadata){
      Composite.register("oj-sample-metric", {
        view: view,
        viewModel: viewModel,
        metadata: JSON.parse(metadata)
      });
     }
    );

    TypeScriptアプリケーションの場合は、次のサンプルのようにimport文を変更します:

    import "ojcss!oj-sample/common/styles/oj-sample-styles";

    ojcssプラグイン・インポートを使用すると、ダウンストリーム開発者はプラグイン・ディレクティブの処理を構成するようにアプリケーションを設定でき、オプションで、利用側アプリケーションがスタイルを定義するときにカスタム・コンポーネント・スタイルシートのロードを抑制できます。

  2. これらの同じコンポーネントについて、コンポーネントのcomponent.jsonファイルを編集して、テーマを定義するSCSS部分を指定する拡張メタデータでコンポーネントを修飾します。
    {
        "name": "metric",
        "pack": "oj-sample",
        "type":"composite",
        "displayName": "Metric Component",
        "license": "https://opensource.org/licenses/UPL",
        "description": "A simple tile that displays a label and value.",
        "version": "4.0.0",
        "jetVersion": ">=8.0.0 <10.0.0",
        "icon": {
            "iconPath": "extension/images/cca-metric.svg",
            "selectedIconPath": "extension/images/cca-metric.svg",
            "hoverIconPath": "extension/images/cca-metric-ovr.svg"
        },
        "properties": {
          . . .
        },
        "events": {
            . . .
        },
        "extension": {
            "themes":{
                "default":"Redwood",
                "unsupportedThemes":["Alta"]
                "partials":{
                  "Redwood":"themes/redwood/_oj-sample-metric.scss"}
          }
            "catalog": {
                . . .
            },
            "vbdt": {
                . . .
            }
        }
    
      }

    このサンプルでは、extension : themes属性によって、コンポーネントでサポートされるテーマの配列が定義されます。各テーマは、そのコンポーネントのテーマ実装のソースとして、ルート部分の相対パスを指します。この定義は、予想されるデフォルト・テーマであるかどうかも示します。コンポーネントは複数のテーマをサポートできますが、デフォルトとしてマークできるのはいずれか一方のみです。

    このメタデータはJETでは必要ありませんが、テーマ適用可能なカスタム・コンポーネントにはお薦めします。この情報は、ダウンストリーム開発者が、これらのSCSS部分を独自のSCSSファイルにプルするようにアプリケーションを設定するために使用されます。その後、アプリケーションを構築して、個々のスタイルシートを結合されたCSSファイルにアセンブルできます。

    通常の使用では、ojcssプラグインとcssプラグインの操作に違いはありません。ただし、利用側アプリケーションでプラグイン・ディレクティブの処理を制御できるようになりました。

    利用側アプリケーションがプラグイン・ディレクティブの処理を制御して、コンポーネントCSSのロードを抑制し、アプリケーションのカスタム・テーマ内でスタイル・クラスを定義する方法を理解するには、「利用側アプリケーションへのテーマ・コンポーネントの組込み」を参照してください。

利用側アプリケーションへのテーマ・コンポーネントの組込み

利用側アプリケーションのテーマのスタイル・クラスを変更することで、適切にテーマ適用されたWebコンポーネントのCSS変数をオーバーライドできます。

カスタム・コンポーネントを使用していて、そのテーマとアプリケーションのテーマが同じ場合、カスタム・コンポーネントをアプリケーションに追加して、変更せずに使用できます。ただし、利用側アプリケーション・テーマによってカスタム・コンポーネントのスタイルが変更された場合は、アプリケーション内のカスタム・コンポーネント・テーマ部分のSCSSファイルを参照する必要があります。

たとえば、アプリケーションのカスタム・テーマでデフォルトのRedwoodテーマの色ランプを変更する場合、アプリケーションに追加するテーマ適用可能なカスタム・コンポーネントで同じ色が継承されるようにする必要があります。利用側アプリケーションによってカスタム・コンポーネントのCSS変数をオーバーライドするこのプロセスでは、使用する各コンポーネントによって提供される部分を組み込む必要があります。このプロセスは静的に定義されるため、テーマ適用を必要とする新しいコンポーネントを利用側アプリケーションに追加するたびに再実行する必要があります。

このプロセスは、基礎となるRedwoodテーマを変更する必要がなく、コアRedwoodスタイルと、使用するカスタム・コンポーネントに定義されている追加のスタイルの両方を統合することでCSSファイルの数を最適化するだけの場合にも使用できます。

始める前に:

  1. テーマ作成プロセスの実行に使用する作業プロジェクトを作成します。
    ojet create redwood-plus-theme-source --template=basic

    この例では、作業プロジェクトの名前はredwood-plus-theme-sourceです。

  2. プロジェクトにテーマのサポートを追加し、カスタム・テーマを作成します。
    ojet add theming
    ojet create theme redwood-plus --basetheme=redwood
    

    この例では、テーマ名redwood-plusによって、カスタム・テーマとすぐに使用できるredwoodテーマ名が区別されます。JETは、リリース11.0.0の時点で、すぐに使用できるredwoodテーマに対する将来の変更の影響を受けにくいもう1つのすぐに使用できるテーマ(stable)をサポートしています。利用側アプリケーションがstableテーマに基づくテーマを使用する場合は、--basetheme引数値としてstableを選択します。

  3. Oracle Component Exchangeを使用してWebコンポーネントを追加する場合は、Component Exchangeへのアクセスを設定します。
    ojet configure --exchange-url=https://xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325/compcatalog/0.2.0
  4. テーマに含めるコンポーネントを追加します。このプロセスにより、テーマ・ソース・プロジェクトのルートにある/jet_componentsキャッシュ・フォルダにコンポーネントがダウンロードされます。

    コンポーネントを1つずつ追加できます。

    ojet add component oj-sample-metric@^4.0.0

    または、パック全体を一度に追加することもできます。

    ojet add pack oj-sample@^4.0.0

    この例では、この項の前のトピックで示した例のコンポーネント名とパック名を再利用します。

    コンポーネントまたはパックを追加する場合は、必要なバージョンを指定する必要があります。コアJETテーマの使用方法と同様に、コンポーネントまたはパックのメジャー・バージョン番号に変更がある場合は、テーマを再構築して再生成できます。

テーマ適用可能なコンポーネントをカスタム・テーマに組み込むには:

  1. カスタム・コンポーネントを追加した作業プロジェクトで、/src/themes/<themeName>/webフォルダを開き、フォルダ構造を調べます。
    /src
      /themes
        /redwood-plus
          /web
            _redwood-plus.components.scss
            _redwood-plus.cssvars.settings.scss
            _redwood-plus.sass.settings.scss
            redwood-plus.scss

    このサンプルでは、3つのSCSS部分ファイルとCSS集計ファイルredwood-plus.scssを示します。テーマ適用可能なカスタム・コンポーネントを使用して作業プロジェクトのテーマをカスタマイズする観点から、4つのファイルに次の目的があります。

    • _redwood-plus.components.sccsを使用すると、JETコアの特定のコンポーネントのみをスタイル設定するように指定して、テーマの全体的なサイズをチューニングできます。通常、コンポーネント・セット全体をスタイル設定するため、このファイルには触れません。カスタム・テーマでのCSSの最適化も参照してください。
    • _redwood-plus.cssvars.settings.scssは、カスタム・テーマのスタイル変更のほとんどを行うために使用するファイルです(変更が必要な場合)。これを使用して、様々なJETコア・コンポーネント(および場合によってはカスタム・コンポーネント)で使用するCSS変数値を設定します。たとえば、JET全体のプライマリ・テキストの色を変更するには、--oj-core-text-color-primaryの値のコメントを解除して設定することで、このファイルでこれを実行できます。この同じ変数がカスタム・コンポーネントのいずれかで使用されている場合は、この共通の変更が共有されます。「JET CLIでのカスタム・テーマの変更」も参照してください。
    • _redwood-plus.sass.settingsは、変更する必要があるが、アニメーション効果などの単純な変数値として表現できないテーマのその他の側面を定義します。基本的なテーマ適用シナリオでは、このファイルに触れる必要はありません。
    • redwood-plus.scssは、テーマ全体のメインCSS集計ファイルであり、redwood-plus.cssファイルとして最終出力に変換されます。
  2. /src/themes/<themeName>/webフォルダで、CSS集計ファイル<themeName>.scssを編集し、作業プロジェクトに追加したテーマ適用可能なカスタム・コンポーネントのimport文を追加します。
    ...
    // import SASS custom variable overrides
    @import "_redwood-plus.sass.settings.scss";
    
    // Imports all jet components styles
    //@import "oj/all-components/themes/redwood/_oj-all-components.scss";
    
    // To optimize performance, consider commenting out the above oj-all-components
    // import and uncomment _redwood-plus.components.scss below.
    // Then in _redwood-plus.components.scss uncomment only the component 
    // imports that your app needs.
    //
      
    // @import "_redwood-plus.components.scss";
    
    // Import components from oj-sample JET Pack
    @import "oj-sample/metric/themes/redwood/_oj-sample-metric.scss";
    @import "oj-sample/input-email/themes/redwood/_input-email.scss";
    @import "oj-sample/input-url/themes/redwood/_input-url.scss";
    
    // import CSS Custom properties
    @import "_redwood-plus.cssvars.settings.scss";

    このサンプルでは、oj-sampleパックの3つのテーマ適用可能なカスタム・コンポーネントのimport文が追加されています。各コンポーネント部分のincludePathを参照しているこれらのimport文をCSS集計ファイルに追加された、示されたコンポーネント部分がカスタム・テーマに組み込まれます。

  3. オプションで、テーマに変更を加えている場合(およびCSSを統合するためだけのプロセスを使用していない場合)、カスタム・コンポーネントを含むサンプル・コンポーネントを作業プロジェクトのindex.htmlページに埋め込んでテーマをテストし、実行できます。その後、テーマが期待どおりに変更されていることを確認できます。ただし、プロジェクトを実行する前に、カスタム・コンポーネントが独自のスタイルシートではなくテーマからスタイルを選択できることを確認する必要があります。
    1. コンポーネントCSSのロードを抑制するには、main.jsファイルを編集し、抑制するCSSのロードを指定するojcss構成セクションをrequirejs構成に追加します。
      requirejs.config(
          {
            baseUrl: 'js',
            ojcss: {
              'exclude': ['oj-sample']
             },
            paths:
            /* DO NOT MODIFY
            ** All paths are dynamically generated from the path_mappings.json file.
            ** Add any new library dependencies in path_mappings json file
            */
            // injector:mainReleasePaths
            {
              ...
            }
            // endinjector
            ,
        
          }
        );
      }());
      

      次に示すように、ojcss構成セクションが //injectorブロックの外に追加されていることを確認します。そうでない場合は、ビルド・プロセスによってセクションが削除され、無視されます。

      このサンプルでは、requirejs構成のojcssセクションで、JETパックoj-sampleの統合スタイルシートが除外されています。ojcssセクションでは、ロードから除外されるrequireJSパスの配列を定義します。この構成は、一致する一貫した信頼性のある参照ベースのパスを使用したコンポーネント内のインポートに依存することに注意してください。

    2. プロジェクトを実行して変更を確認します。
      ojet serve --theme=redwood-plus
  4. /src/themes/<myTheme>/theme.jsonファイルのバージョン番号をターゲットCSSに適した番号に更新し、統合されたテーマを構築します。デフォルトでは、最初のバージョン番号は0.0.1です。
    ojet build --theme=redwood-plus

Webコンポーネントのテスト

クライアント側のJavaScriptアプリケーション用の好みのテスト・ツールを使用して、Oracle JET Webコンポーネントをテストします。

選択したテスト方法に関係なく、テストでWebコンポーネントの次のものが完全に実行されるようにしてください。

  • ViewModel (存在する場合)

    コード・カバレッジ番号を使用してテスト結果を検証することをお薦めします。

  • HTMLビュー

    条件付きでレンダリングされる場合があるすべてのDOMブランチを追加し、デフォルト・コンテンツあり/なしですべてのスロットをテストしてください。

  • プロパティおよびプロパティ値

  • イベント

  • メソッド

  • アクセシビリティ

  • セキュリティ

Oracle JETアプリケーションのテストの詳細は、「Oracle JETアプリケーションのテスト」を参照してください。

ページへのWebコンポーネントの追加

Oracle JET Webコンポーネントを使用するには、Webコンポーネントのローダー・ファイルをアプリケーションに登録する必要があり、アプリケーションのHTMLにWebコンポーネント要素を含める必要もあります。必要に応じて、サポートするCSSまたはファイルを追加できます。

  1. Webコンポーネントのルート・フォルダでcomponent.jsonを開き、Oracle JETのバージョンがjetVersionで指定されたバージョンと互換性があることを確認してください。

    たとえば、demo-cardの例では次のjetVersionが指定されています。

    "jetVersion": ">=3.0.0 <17.1.0"

    これは、コンポーネントが、3.0.0以上で17.1.0未満のJETバージョンと互換性があることを示しています。

    使用しているOracle JETバージョンがjetVersionよりも前のバージョンである場合は、コンポーネントを使用する前にOracle JETのバージョンを更新する必要があります。使用しているOracle JETバージョンがjetVersionより上の場合は、開発者に連絡して、更新バージョンのコンポーネントを入手してください。

  2. アプリケーションのindex.htmlまたはメイン・アプリケーションHTMLに、コンポーネントおよび関連プロパティの宣言を追加します。

    たとえば、demo-cardスタンドアロンWebコンポーネントを使用するには、それをindex.htmlファイルに追加し、nameavatarwork-titlework-numberemailおよびbackground-imageの宣言を追加します。

    <div id="composite-container" class="oj-flex oj-sm-flex-items-initial">
       <oj-bind-for-each data="[[employees]]">
         <template>
           <demo-card class="oj-flex-item" 
                      name="[[$current.data.name]]" 
                      avatar="[[$current.data.avatar]]" 
                      work-title="[[$current.data.title]]" 
                      work-number="[[$current.data.work]]" 
                      email="[[$current.data.email]]">
           </demo-card>  
         </template>
       </oj-bind-for-each>
    </div>

    JETパック内のコンポーネントの場合、HTMLタグ名はコンポーネントの完全名です。パックのメンバー・コンポーネントの完全名は、常にパック名とコンポーネント名を連結したものです。これは、パック・レベルのcomponent.jsonファイル(パックのルート・フォルダのjet-compositesにある)のdependencies属性によって指定されます。たとえば、JETパックmy-packのメンバーであるコンポーネントwidget-1の完全名は次のようになり、これをHTMLのタグ名として参照できます。

    my-pack-widget-1

    フレームワークでは、マークアップの属性名がコンポーネントのプロパティにマップされることに注意してください。

    • 属性名は小文字に変換されます。たとえば、workTitle属性はworktitleプロパティにマップされます。

    • ダッシュが含まれる属性名は、ダッシュの後の最初の文字を大文字にして、ダッシュを削除することで、camelCaseに変換されます。たとえば、work-title属性は、workTitleプロパティにマップされます。

    次のマークアップに示すように、マップされたプロパティにプログラムによってアクセスできます。

    <h5><oj-bind-text value="[[properties.workTitle]]"></oj-bind-text></h5>
  3. アプリケーションのViewModelで、前のステップで宣言したプロパティの値を設定し、コンポーネントのローダー・ファイルをアプリケーション依存性のリストに追加します。

    たとえば、次のコードは、アプリケーションのRequireJSブートストラップ・ファイルにViewModelを追加します。このコードは、jet-composites/demo-card/loader依存性も定義しています。

    require(['ojs/ojbootstrap', 'knockout', 'ojs/ojknockout', 'demo-card/loader'],
    function(Bootstrap, ko) {
      function model() {      
        var self = this;
        self.employees = [
          {
            name: 'Deb Raphaely',
            avatar: 'images/composites/debraphaely.png',
            title: 'Purchasing Director',
            work: 5171278899,
            email: 'deb.raphaely@oracle.com'
          },
          {
            name: 'Adam Fripp',
            avatar: null,
            title: 'IT Manager',
            work: 6501232234,
            email: 'adam.fripp@oracle.com'
          }
        ];
      }
    
      Bootstrap.whenDocumentReady().then(function()
        {
          ko.applyBindings(new model(), document.getElementById('composite-container'));
        }
      );
    });
    

    JETパックの場合は、パック・ルートとパックに含まれるコンポーネントのフォルダ名に基づくパスを指定して、JETパック用のローダー・ファイルを追加します。

    'my-pack/widget-1/loader'
  4. 必要に応じて、サポートするCSS、フォルダおよびファイルを追加します。

    たとえば、デモ・カードの例では、アプリケーションのdemo.cssで連絡先カードの背景イメージを定義しています:

    #composite-container demo-card .demo-card-front-side {
        background-image: url('images/composites/card-background_1.png');
    }
    

Webコンポーネントのビルド

Oracle JET Webコンポーネントを作成することで、ファイルを最適化し、コンシューマと共有可能なコンポーネントの縮小フォルダを生成できます。

Webコンポーネントを構成し、様々なアプリケーションで使用する準備ができたら、スタンドアロンWebコンポーネント、JETパックおよびリソース・コンポーネントといったタイプのWebコンポーネントをビルドできます。JETツールを使用してこれらのコンポーネントをビルドすると、最適化されたコンポーネント・ファイルを含む縮小コンテンツが生成されます。この縮小バージョンのコンポーネントは、コンシューマと簡単に共有して使用できます。たとえば、Oracle Component Exchangeに公開する前にコンポーネントをビルドします。Webコンポーネントをビルドするには、コンポーネントを含むJETアプリケーションのルート・フォルダから次のコマンドを使用します:

ojet build component my-web-component-name

たとえば、Webコンポーネント名がdemo-card-exampleの場合は、次のコマンドを使用します。

ojet build component demo-card-example

JET Packの場合は、パック名を指定します。

ojet build component my-pack-name

パック内の個別のコンポーネントのビルドはサポートされていないことに注意してください。パック全体を一度にビルドする必要があります。

このコマンドによって、Oracle JET Webアプリケーションのweb/js/jet-composites/demo-card-example/x.x.xディレクトリに/minフォルダが作成されます。ここで、x.x.xはコンポーネントのバージョン番号です。/minフォルダにはWebコンポーネント・ファイルの縮小(リリース)バージョンが含まれます。

参照コンポーネントでは縮小やバンドルは必要ないため、ビルドする必要はありません。

Webコンポーネントをビルドする場合:

  • JETアプリケーションに複数のコンポーネントが含まれる場合、コンポーネントを含むJETアプリケーションをビルドし、すべてのコンポーネントをまとめてビルドして最適化できます。コンポーネント名を指定してbuild componentコマンドを実行すると、単一コンポーネントをビルドできます。

  • オプションで、buildコマンドとともに--releaseフラグを使用することはできますが、buildコマンドではコンポーネントのデバッグと縮小バージョンの両方が生成されるため、必須ではありません。

  • デバッグに適した可読性の高いコンパイル出力を生成する場合は、オプションでbuildコマンドとともに--optimize=noneフラグを使用できます。コンポーネントのloader.jsファイルには縮小アプリケーション・ソースが含まれますが、元のソースの改行および空白が保持されるため、内容の可読性は向上します。

VComponentベースのWebコンポーネントのAPIドキュメントの生成

Oracle JET CLIには、開発するVComponentベースのWebコンポーネント(VComponent)のAPIドキュメントの生成を支援するためのコマンド(ojet add docgen)が含まれています。

プロジェクトのルートからコマンドを実行すると、JSDoc NPMパッケージがインストールされ、apidoc_templateディレクトリがプロジェクトのsrcディレクトリに追加されます。apidoc_templateディレクトリには、後でVComponent用に生成するAPIリファレンス・ドキュメントの適切なタイトル、サブタイトルおよびフッター情報(コピーライト情報など)でカスタマイズできる次のファイルが含まれています。

footer.html
header.html
main.html

次の例のように、VComponentのソース・ファイルにコメントを記述します:

import { ExtendGlobalProps, registerCustomElement } from "ojs/ojvcomponent";
. . .

type Props = Readonly<{
  message?: string;
  address?: string;
}>;

/**
 *
 * @ojmetadata version "1.0.0"
 * @ojmetadata displayName "A user friendly, translatable name of the component"
 * @ojmetadata description "<p>Write a description here.</p>
                            <p>Use HTML tags to put in new paragraphs</p>
                            <ul>
                                <li>Bullet list item 1</li>
                                <li>Bullet list item 2</li></ul>
         * <p>Everything before the closing quote is rendered</p>
 * "
 *
 */


function StandaloneVcompFuncImpl({ address = "Redwood shores", 
                         message = "Hello from  standalone-vcomp-func" }: Props) {
  return (
    <div>
    . . .
    </div>
  );
}

ソース・ファイルでのVComponentのAPIの文書化が完了したら、コンポーネントがJETパック(ojet build component component-nameまたはojet build component jet-pack-name)の一部である場合、コンポーネントまたはJETパックに対してbuildコマンドを実行し、appRootDir/web/js/jet-composites/component-or-pack-name/vcomponent-version/docsディレクトリにAPIリファレンス・ドキュメントを生成します。

次の/docsディレクトリ・リストは、スタンドアロンVComponentに対してOracle JET CLIによって生成されるファイルを示しています。コンポーネントを含むOracle JETアプリケーションをビルドして、APIドキュメントを生成することはできません。個々のVComponentまたはVComponentを含むJETパックをビルドする必要があります。Oracle JET CLI ojet add docgenコマンドを使用して、CCAベースのWebコンポーネントのAPIドキュメントを生成することもできません。


appRootDir/web/js/jet-composites/standalone-vcomp-func/1.0.0/docs
|   index.html
|   jsDocMd.json
|   standalone-vcomp-func.html
|   standalone.StandaloneVcompFunc.html
|
+---scripts
|   |   deprecated.js
|   |
|   \---prettify
|           Apache-License-2.0.txt
|           lang-css.js
|           prettify.js
|
\---styles
    |   jsdoc-default.css
    |   prettify-jsdoc.css
    |   prettify-tomorrow.css
    |
    \---images
            bookmark.png
            linesarrowup.png
            linesarrowup_blue.png
            linesarrowup_hov.png
            linesarrowup_white.png
            oracle_logo_sm.png

なお、生成されたAPIドキュメントの外観を変更するために代替ロゴまたはCSSスタイル(あるいはその両方)を含める場合は、ディレクトリappRootDir/node_modules/@oracle/oraclejet/dist/jsdoc/static/styles/のコンテンツを更新してください。

Webコンポーネントのパッケージ化

コマンドライン・インタフェースで、縮小Oracle JET Webコンポーネントの共有可能なzipファイル・アーカイブを作成できます。

他の開発者とWebコンポーネントを共有する場合、アプリケーションの/webjet-compositesサブフォルダに含まれる生成済出力のアーカイブ・ファイルを作成できます。スタンドアロンWebコンポーネントまたはリソース・コンポーネントをビルドしたら、JETツールを使用してpackageコマンドを実行し、Webコンポーネントのコンパイル済の縮小ソースを含むzipファイルを作成します。
ojet package component my-web-component-name
JETパックの場合も同様にファイル・システムから直接zipファイルを作成することはできません。JETツールを使用してJETパックをパッケージ化する必要があります。/jet-composites/<packName>サブフォルダ内の出力には、ネストされたコンポーネント・フォルダが含まれますが、ツールを使用すると確実にコンポーネントごとに独自のzipファイルが作成されるためです。
ojet package pack my-JET-Pack-name

packageコマンドは、/web/js/jet-compositesディレクトリからコンポーネントの縮小ソースをパッケージ化し、それを含むアプリケーションのルートにある/distフォルダ内のzipファイルとして使用できるようにします。このzipファイルの/minサブフォルダには、指定されたコンポーネントとそのコンポーネントの縮小バージョンの両方が含まれます。

参照コンポーネントでは縮小やバンドルは必要ないため、ビルドする必要はありません。コンポーネントのフォルダの単純なzipアーカイブを作成することで、参照コンポーネントをアーカイブできます。

パッケージ化されたコンポーネントのzipアーカイブは、たとえば、「Oracle Component ExchangeへのWebコンポーネントの公開」に示したように、Oracle Component Exchangeで共有するために適しています。公開するコンポーネントを編成するために、JETツールにより、JETパックと個々のコンポーネントのcomponent.jsonファイルのversionプロパティの値がdistフォルダ内の生成されたzipに追加されます。たとえば、version値が1.0.0であるコンポーネント・パックmy-component-packがあり、パック内の個々のコンポーネント(my-widget-1など)のバージョン値も1.0.0の場合、生成されたファイルのzipファイル名は次のようになります:

appRootDir/dist/
my-web-component-name_1-0-0.zip
my-component-pack_1-0-0.zip
my-component-pack-my-widget-1_1-0-0.zip
my-component-pack-my-widget-2_1-0-0.zip
my-component-pack-my-widget-3_1-0-0.zip

コンポーネントをCDNにアップロードするときに、アーカイブ・ファイルも生成できます。CDNの場合は、「CDNでのWebコンポーネントのアップロードおよび消費」で説明しているように、コンポーネントを共有するために追加のステップが必要です。

共有Oracle Component Exchangeをホストするためのプロジェクトの作成

他の開発者が再利用できるように様々なマシンにWebコンポーネントを格納して共有する場合、Oracle Visual Builder Studioで作成するコンポーネント交換を使用できます。

Webコンポーネントを共有する場合は、一般に、共有交換をホストする専用プロジェクトを設定する必要があります。Oracle Visual Builder Studio内のすべてのプロジェクトにはプライベートのコンポーネント交換インスタンスがありますが、共有交換の場合は、アップロードされたコンポーネントに他の開発者がアクセスできます。同じプロジェクトを共有交換で使用して、コンポーネントのソース・コード・リポジトリをホストできます。

共有交換を作成するには:

  1. Oracle Visual Builder Studioで新規プロジェクトを作成します。
    この画像は、Oracle Visual Builder Studioの「新規プロジェクト」ページです。
  2. 新規プロジェクトの初期リポジトリ・テンプレートを選択します。
    この画像は、Oracle Visual Builder Studioの「新規プロジェクト」の「テンプレート」ページです。
  3. デフォルト設定のままにするか、オプションでコンポーネント・ソース・コードをインポートするための設定を選択し、「終了」をクリックします。
    この画像は、Oracle Visual Builder Studioのプロジェクト・プロパティ・ページです。
  4. プロジェクトのプロビジョニング画面で、「コンポーネント交換」が作成中のサービスの1つとして存在することを確認します。
    この画像は、Oracle Visual Builder Studioがホストする共有コンポーネント・カタログのホーム・ページです。
  5. 公開されたコンポーネントにアクセスする必要があるすべてのユーザーをメンバーとしてプロジェクトに追加して、共有します。これにより、自分のユーザー名とパスワードを使用して、共有コンポーネント交換にアクセスできるようになります。
プロジェクトが作成されたら、正しいURLを取得し、Oracle JETツールで使用して共有コンポーネント交換にアクセスできます。「Oracle Component ExchangeへのWebコンポーネントの公開」を参照してください。

Oracle Component ExchangeへのWebコンポーネントの公開

他の開発者が再利用できるように様々なマシンにWebコンポーネントを格納して共有する場合、Oracle JET CLI (コマンドライン・インタフェース)を使用して、Oracle Visual Builder Studioで定義された共有コンポーネント交換へのアクセスを構成してから、公開プロジェクトにコンポーネントを公開できます。

Webコンポーネントを共有する場合、Oracle JET CLIを使用して、ターゲット・コンポーネント交換へのURLを指定することで、共有コンポーネント交換へのアクセスを構成できます。特定のコンポーネント交換用のJETツールを構成したら、JET CLIでpublish componentコマンドを実行して、指定したコンポーネントをアップロードできます。アクセス権を持つユーザーは、CLIを使用して、コンポーネント交換でコンポーネントをキーワードで検索し、コンポーネントをWebアプリケーション・プロジェクトに追加できます。

始める前に:

コンポーネントを共有コンポーネント交換に公開するには:

  1. Oracle JETツールの構成に使用できる共有コンポーネント交換のURLを取得します。
    1. 作成した共有コンポーネント交換から、GITリポジトリのクローン作成に使用するURLをコピーします。URLは次のようになります。
      https://john.doe@example.org@xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325/scm/sharedcomponentcatalog.git
    2. コピーしたURLを使用して、ユーザー名の接頭辞(john.doe@example.org@など)を削除し、/scm以降の要素を削除して、プロジェクトのみのルートを取得します。次のようになります。
      https://xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325
    3. 次に、/compcatalog/0.2.0を追加します。

      この例では、Oracle JETツールに必要なExchange URLは次のようになります。

      https://xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325/compcatalog/0.2.0
  2. Oracle JET CLIでojet configureコマンドを実行し、コンポーネント交換プロジェクトにアクセスするためにOracle JETツールを構成します。取得したコンポーネント交換URLを渡すには、コマンドに--exchange-urlフラグを設定します。
    ojet configure --exchange-url=https://xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325/compcatalog/0.2.0

    ヒント:

    JET CLIを使用して、ユーザーのすべてのプロジェクトに対してグローバルなExchange URLを定義できます:

    ojet configure --global --exchange-url=myExchange.org

    プロジェクト・レベルでojet configureコマンドに渡すURLは、グローバル定義をオーバーライドします。

  3. Oracle JET CLIで、publish componentコマンドを実行して、構成されたコンポーネント交換にコンポーネントを公開します。
    ojet publish component my-demo-card

    オプションで、publishコマンドでコンポーネント交換のログイン・ユーザー名とパスワードを指定できます。詳細を確認するには、CLIにojet help publishと入力してください。

Oracle JETツールでは、コンポーネント名などのキーワードを使用してsearch exchangeコマンドを実行することで、構成されたコンポーネント交換を検索できます。また、構成されたコンポーネント交換に対してadd componentコマンドを実行することで、コンポーネントをWebアプリケーションに追加できます。詳細を確認するには、JET CLIでojet helpを使用します。

CDNでのWebコンポーネントのアップロードおよび消費

Webコンポーネントをパッケージ化してコンテンツ配信ネットワーク(CDN)で使用できるようにし、アプリケーションでコンポーネントを再利用できます。

コンポーネントのCDNでの位置は、コンポーネントのcomponent.jsonファイルで定義されるコンポーネント・メタデータに含めることができます。これにより、Oracle JETツールやOracle Visual Builderなどのツールは、リリース・モードでアプリケーションをビルドする際に、CDNの場所を指すことができます。

CDN情報は、component.jsonファイルのpaths属性を使用してエンコードされます。典型的な例は、次のようになります。

{
  "name": “demo-samplecomponent",
  "displayName": “Sample component",
  "version": "1.0.0",
  "paths": {
    "cdn": {
      "min": "https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0/min",
      "debug": "https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0"
    }
  },
...

次のノートは、指定するpaths属性に適用されます:

  • CDNの正確なルートの場所はCDNプロバイダによって異なります。これは必要な場所の最後の部分です。

  • この場所のフォルダにはコンポーネントと同じ名前が付き(この例ではdemo-samplecomponent)、その後にコンポーネントのバージョン番号(1.0.0)が続きます。コンポーネントの新しいバージョンをリリースすると、コンポーネント・ルートの下に新しいバージョン番号のフォルダが作成されます。

  • コンポーネントにminパスとdebugパスの両方を指定できます。debugパスはオプションです。

CDN配布の準備をするには、Oracle JETコマンドライン・インタフェースでpackage componentコマンドを実行してコンポーネントをパッケージ化します。これにより、コンポーネントと同じ名前のzipファイル(たとえば、demo-samplecomponent.zip)が、それを含むOracle JETアプリケーションの/distフォルダに生成されます。このzipファイルの/minサブフォルダには、指定されたコンポーネントとそのコンポーネントの縮小バージョンの両方が含まれます。

component.jsonファイルで指定される、CDNの/<component-name>/<version>フォルダの下に作成したzipファイルを解凍します。

CDNでコンポーネントが使用できるようになったら、コンポーネントのrequireJSパスをコンポーネントに対して指定したCDNの場所に指定して、JETアプリケーションで使用できます。Oracle JETツールを使用すると、自動的に指定されます。ただし、requireJSパスを手動で定義する必要がある場合、main.jsファイルのこのマッピングは次のようになります:

requirejs.config(
    {
      baseUrl: 'js',
      paths:
      {
        'demo-samplecomponent': '"https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0/min',
      ...

コンポーネントへの参照は、パス<component-name>/loaderを使用して作成できます。