SPAの統合

Reactで記述されたシングルページアプリケーション(SPA)のソースコードをAdobe Experience Manager(AEM)プロジェクトと統合する方法を説明します。 webpack開発サーバーなどの最新のフロントエンドツールを使用して、AEM JSONモデルAPIに対するSPAを迅速に開発する方法を説明します。

目的

  1. SPAプロジェクトとAEMをクライアント側ライブラリと統合する方法について説明します。
  2. 専用のフロントエンド開発にWebpack開発サーバーを使用する方法を説明します。
  3. AEM JSONモデルAPIに対する開発に、proxy​と静的な​mock​ファイルの使用を調べます。

作成する内容

この章では、SPAとの統合方法を理解するために、AEMに対していくつかの小さな変更を加えます。
この章では、単純なHeaderコンポーネントをSPAに追加します。 この​静的 Headerコンポーネントを構築する過程で、AEM SPA開発にいくつかのアプローチが使用されます。

AEMの新しいヘッダー

SPAが拡張され、静的コンポーネントが追加さ Header れます

前提条件

ローカル開発環境の設定に必要なツールと手順を確認します。 この章は、「プロジェクトを作成」の章の続きですが、必要な操作は、SPA対応のAEMプロジェクトだけです。

統合アプローチ

AEMプロジェクトの一部として、2つのモジュールが作成されました。ui.appsui.frontendが表示されます。

ui.frontendモジュールは、すべてのSPAソースコードを含むwebpackプロジェクトです。 SPAの開発およびテストの大部分は、webpackプロジェクトでおこなわれます。 実稼動ビルドがトリガーされると、SPAはwebpackを使用して構築およびコンパイルされます。 コンパイル済みのアーティファクト(CSSおよびJavaScript)がui.appsモジュールにコピーされ、AEMランタイムにデプロイされます。

ui.frontendハイレベルアーキテクチャ

SPA統合の概要です。

フロントエンドビルドに関する追加情報は、こちらを参照してください。

InspectとSPAの統合

次に、 ui.frontendモジュールを調べて、AEMプロジェクトのアーキタイプによって自動生成されたSPAを理解します。

  1. 任意のIDEで、AEMプロジェクトを開きます。 このチュートリアルでは、Visual Studio Code IDEを使用します。

    VSCode - AEM WKND SPA Project

  2. ui.frontendフォルダーを展開し、検査します。 ファイルui.frontend/package.jsonを開きます。

  3. dependenciesの下に、react-scriptsを含むreactに関連する複数のが表示されます。

    ui.frontendは、Reactアプリを作成またはCRA(短くして)に基づくReactアプリケーションです。 react-scriptsバージョンは、使用されるCRAのバージョンを示します。

  4. @adobeというプレフィックスが付いた依存関係もいくつかあります。

    "@adobe/aem-react-editable-components": "~1.1.2",
    "@adobe/aem-spa-component-mapping": "~1.1.0",
    "@adobe/aem-spa-page-model-manager": "~1.3.3",
    "@adobe/aem-core-components-react-base": "1.1.8",
    "@adobe/aem-core-components-react-spa": "1.1.7",
    

    上記のモジュールは、AEM SPA Editor JS SDKを構成し、SPAコンポーネントをAEMコンポーネントにマッピングできるようにする機能を提供します。

    また、AEM WCM Components - React Core実装およびAEM WCM Components - Spa Editor - React Core実装も含まれます。 これらは、すぐに使用できるAEMコンポーネントにマッピングされる、再利用可能なUIコンポーネントのセットです。 これらは、そのまま使用するように設計され、プロジェクトのニーズに合わせてスタイル設定されます。

  5. package.jsonファイルには、次のように複数のscriptsが定義されています。

    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build && clientlib",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
    }
    

    これらは、React Appを作成することで利用可能なの標準ビルドスクリプトです。

    唯一の違いは、&& clientlibbuildスクリプトに追加することです。 この追加の命令は、ビルド中に、コンパイル済みのSPAをクライアント側ライブラリとしてui.appsモジュールにコピーする役割を持ちます。

    npmモジュールaem-clientlib-generatorを使用して、これを容易にします。

  6. ui.frontend/clientlib.config.js ファイルを検査します。この設定ファイルは、aem-clientlib-generatorでクライアントライブラリの生成方法を決定するために使用されます。

  7. ui.frontend/pom.xml ファイルを検査します。このファイルは、ui.frontendフォルダーをMavenモジュールに変換します。 pom.xmlファイルが更新され、Mavenのビルド中にfrontend-maven-pluginを​test​および​build​にSPAを使用するようになりました。

  8. ui.frontend/src/index.jsにあるファイルindex.jsをInspectにします。

    //ui.frontend/src/index.js
    ...
    document.addEventListener('DOMContentLoaded', () => {
        ModelManager.initialize().then(pageModel => {
            const history = createBrowserHistory();
            render(
            <Router history={history}>
                <App
                history={history}
                cqChildren={pageModel[Constants.CHILDREN_PROP]}
                cqItems={pageModel[Constants.ITEMS_PROP]}
                cqItemsOrder={pageModel[Constants.ITEMS_ORDER_PROP]}
                cqPath={pageModel[Constants.PATH_PROP]}
                locationPathname={window.location.pathname}
                />
            </Router>,
            document.getElementById('spa-root')
            );
        });
    });
    

    index.js は、SPAのエントリポイントです。ModelManager は、AEM SPA Editor JS SDKで提供されます。これは、を呼び出し、アプリケーションにpageModel (JSONコンテンツ)を挿入する役割を果たします。

  9. ui.frontend/src/import-components.jsにあるimport-component.jsファイルをInspectします。 このファイルは、初期設定の​Reactコアコンポーネント​を読み込み、プロジェクトで使用できるようにします。 次の章では、AEMコンテンツとSPAコンポーネントのマッピングを調べます。

静的なSPAコンポーネントの追加

次に、新しいコンポーネントをSPAに追加し、変更をローカルのAEMインスタンスにデプロイします。 これは、SPAの更新方法を示すために、簡単な変更です。

  1. ui.frontendモジュールのui.frontend/src/componentsの下に、Headerという名前の新しいフォルダーを作成します。

  2. Headerフォルダーの下にHeader.jsという名前のファイルを作成します。

    ヘッダーフォルダーとファイル

  3. Header.js に以下を入力します。

    //Header.js
    import React, {Component} from 'react';
    
    export default class Header extends Component {
    
        render() {
            return (
                    <header className="Header">
                        <div className="Header-container">
                            <h1>WKND</h1>
                        </div>
                    </header>
            );
        }
    }
    

    上記は、静的なテキスト文字列を出力する標準のReactコンポーネントです。

  4. ui.frontend/src/App.js ファイルを開きます。これは、アプリケーションのエントリポイントです。

  5. App.jsを次のように更新し、静的Headerを含めます。

      import { Page, withModel } from '@adobe/aem-react-editable-components';
      import React from 'react';
    + import Header from './components/Header/Header';
    
      // This component is the application entry point
      class App extends Page {
      render() {
          return (
          <div>
    +       <Header />
             {this.childComponents}
             {this.childPages}
         </div>
    
  6. 新しいターミナルを開き、ui.frontendフォルダーに移動してnpm run buildコマンドを実行します。

    $ cd aem-guides-wknd-spa
    $ cd ui.frontend
    $ npm run build
    ...
    Compiled successfully.
    
    File sizes after gzip:
    
    118.95 KB (-33 B)  build/static/js/2.489f399a.chunk.js
    1.11 KB (+48 B)    build/static/js/main.6cfa5095.chunk.js
    806 B              build/static/js/runtime-main.42b998df.js
    451 B              build/static/css/main.e57bbe8a.chunk.css
    
  7. ui.apps フォルダーに移動し、ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/clientlibs/clientlib-reactの下に、コンパイル済みのSPAファイルがui.frontend/buildフォルダーからコピーされているのがわかります。

    ui.appsで生成されたクライアントライブラリ

  8. ターミナルに戻り、 ui.appsフォルダーに移動します。 次のMavenコマンドを実行します。

    $ cd ../ui.apps
    $ mvn clean install -PautoInstallPackage
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  9.629 s
    [INFO] Finished at: 2020-05-04T17:48:07-07:00
    [INFO] ------------------------------------------------------------------------
    

    これにより、AEMのローカル実行インスタンスにui.appsパッケージがデプロイされます。

  9. ブラウザータブを開き、http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.htmlに移動します。 これで、Headerコンポーネントの内容がSPAに表示されます。

    初期ヘッダー実装

    上記の手順は、プロジェクトのルートからMavenビルドをトリガーすると(つまりmvn clean install -PautoInstallSinglePackage)、自動的に実行されます。 これで、SPAとAEMのクライアント側ライブラリ間の統合の基本を理解する必要があります。 静的なHeaderコンポーネントの下のAEMでは、引き続きTextコンポーネントを編集および追加できます。

Webpack Dev Server - JSON APIのプロキシ

前の演習で見たように、クライアントライブラリをビルドしてAEMのローカルインスタンスに同期するには、数分かかります。 これは最終テストでは許容されますが、SPA開発の大部分には理想的ではありません。

webpack-dev-serverを使用して、SPAを迅速に開発できます。 SPAは、AEMで生成されたJSONモデルによって駆動されます。 この演習では、AEMの実行中のインスタンスのJSONコンテンツが​プロキシ​されて開発サーバーに送られます。

  1. IDEに戻り、ファイルui.frontend/package.jsonを開きます。

    次のような行を探します。

    "proxy": "http://localhost:4502",
    

    Reactアプリを作成は、APIリクエストをプロキシする簡単なメカニズムを提供します。 不明なリクエストはすべて、ローカルのAEMクイックスタートであるlocalhost:4502を介してプロキシされます。

  2. ターミナルウィンドウを開き、 ui.frontendフォルダーに移動します。 npm start コマンドを実行します。

    $ cd ui.frontend
    $ npm start
    ...
    Compiled successfully!
    
    You can now view wknd-spa-react in the browser.
    
    Local:            http://localhost:3000
    On Your Network:  http://192.168.86.136:3000
    
    Note that the development build is not optimized.
    To create a production build, use npm run build.
    
  3. 新しいブラウザータブを開き(まだ開いていない場合)、http://localhost:3000/content/wknd-spa-react/us/en/home.htmlに移動します。

    Webpack開発サーバー — プロキシjson

    AEMと同じコンテンツが表示されますが、オーサリング機能が有効になっていないはずです。

    メモ

    AEMのセキュリティ要件により、同じブラウザーで、別のタブでローカルのAEMインスタンス(http://localhost:4502)にログインする必要があります。

  4. IDEに戻り、src/components/HeaderフォルダーにHeader.cssという名前のファイルを作成します。

  5. Header.cssに以下を入力します。

    .Header {
        background-color: #FFEA00;
        width: 100%;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 99;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.24);
    }
    
    .Header-container {
        display: flex;
        max-width: 1024px;
        margin: 0 auto;
        padding: 12px;
    }
    
    .Header-container h1 {
        letter-spacing: 0;
        font-size: 48px;
    }
    

    VSCode IDE

  6. Header.jsを再度開き、Header.cssを参照する次の行を追加します。

      //Header.js
      import React, {Component} from 'react';
    + require('./Header.css');
    

    変更内容を保存します。

  7. http://localhost:3000/content/wknd-spa-react/us/en/home.htmlに移動して、スタイルの変更が自動的に反映されることを確認します。

  8. Page.cssui.frontend/src/components/Page)ファイルを開きます。パディングを修正するには、次の変更を行います。

    .page {
      max-width: 1024px;
      margin: 0 auto;
      padding: 12px;
      padding-top: 50px;
    }
    
  9. ブラウザー(http://localhost:3000/content/wknd-spa-react/us/en/home.html)に戻ります。 アプリに対する変更がすぐに反映されていることを確認します。

    ヘッダーに追加されたスタイル

    コンテンツをプロキシしているので、AEMで引き続きコンテンツを更新し、webpack-dev-server​に反映されるのを確認できます。

  10. ターミナルでctrl+cを使用してwebpack開発サーバーを停止します。

AEMへのSPAアップデートのデプロイ

Headerに加えられた変更は、現在、webpack-dev-server​でのみ表示されます。 更新したSPAをAEMにデプロイして、変更を確認します。

  1. プロジェクトのルート(aem-guides-wknd-spa)に移動し、Mavenを使用してAEMにプロジェクトをデプロイします。

    $ cd ..
    $ mvn clean install -PautoInstallSinglePackage
    
  2. http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.htmlに移動します。 更新されたHeaderとスタイルが適用されているのが確認できます。

    AEMのヘッダーの更新

    更新されたSPAがAEMになったので、オーサリングを続行できます。

おめでとうございます。

これで、SPAを更新し、AEMとの統合を確認しました。 webpack-dev-server​を使用してAEM JSONモデルAPIに対するSPAを開発する方法を知っています。

次の手順

SPAコンポーネントのAEMコンポーネントへのマッピング - AEM SPA Editor JS SDKを使用して、ReactコンポーネントをAdobe Experience Manager(AEM)コンポーネントにマッピングする方法を説明します。コンポーネントマッピングを使用すると、AEM SPA Editor内で、従来のAEMオーサリングと同様に、SPAコンポーネントを動的に更新できます。

(ボーナス)Webpack Dev Server — モックJSON API

迅速な開発のもう1つのアプローチは、静的JSONファイルをJSONモデルとして機能させることです。 JSONを「モック」することで、ローカルのAEMインスタンスへの依存関係を削除します。 また、フロントエンド開発者は、機能をテストし、JSON APIに対する変更を促進するためにJSONモデルを更新でき、後でバックエンド開発者によって実装されます。

モックJSONの初期設定には、ローカルのAEMインスタンス​が必要です。

  1. IDEに戻り、ui.frontend/publicに移動し、mock-contentという名前の新しいフォルダーを追加します。

  2. ui.frontend/public/mock-contentの下にmock.model.jsonという名前の新しいファイルを作成します。

  3. ブラウザーで、http://localhost:4502/content/wknd-spa-react/us/en.model.jsonに移動します。

    これは、アプリケーションを実行している AEM から書き出した JSON です。JSON 出力をコピーします。

  4. 前の手順のJSON出力をファイルmock.model.jsonに貼り付けます。

    モックモデルJsonファイル

  5. index.htmlui.frontend/public/index.html)ファイルを開きます。変数%REACT_APP_PAGE_MODEL_PATH%を指すようにAEMページモデルのメタデータプロパティを更新します。

        <!-- AEM page model -->
        <meta
           property="cq:pagemodel_root_url"
           content="%REACT_APP_PAGE_MODEL_PATH%"
        />
    

    cq:pagemodel_root_urlの値に変数を使用すると、プロキシとモックjsonモデルの切り替えが容易になります。

  6. ファイルui.frontend/.env.developmentを開き、次の更新を行ってREACT_APP_PAGE_MODEL_PATHの以前の値をコメントアウトします。

    + PUBLIC_URL=/
    - PUBLIC_URL=/etc.clientlibs/wknd-spa-react/clientlibs/clientlib-react/resources
    
    - REACT_APP_PAGE_MODEL_PATH=/content/wknd-spa-react/us/en.model.json
    + REACT_APP_PAGE_MODEL_PATH=/mock-content/mock.model.json
    
    REACT_APP_ROOT=/content/wknd-spa-react/us/en/home.html
    
  7. 現在実行中の場合は、webpack-dev-server​を停止します。 ターミナルから​webpack-dev-server​を起動します。

    $ cd ui.frontend
    $ npm start
    

    http://localhost:3000/content/wknd-spa-react/us/en/home.htmlに移動すると、proxy jsonで使用されているのと同じ内容のSPAが表示されます。

  8. 前に作成したmock.model.jsonファイルに小さな変更を加えます。 更新されたコンテンツが​webpack-dev-server​にすぐに反映されます。

    モックモデルのjsonの更新

JSONモデルを操作し、実際のSPAへの影響を確認できることは、開発者がJSONモデルAPIを理解するのに役立ちます。 また、フロントエンドとバックエンドの両方の開発を並行しておこなうこともできます。

env.developmentファイル内のエントリを切り替えて、JSONコンテンツを使用する場所を切り替えることができるようになりました。

# JSON API via proxy to AEM
#REACT_APP_PAGE_MODEL_PATH=/content/wknd-spa-react/us/en.model.json

# JSON API via static mock file
REACT_APP_PAGE_MODEL_PATH=/mock-content/mock.model.json

このページ