AEM開発者ブログ by YAMATO

アドビ社のデリバリーパートナー大和株式会社のAEM開発者ブログです。

embed[ ]かdependencies[ ]か、それが問題だ。- AEM Clientlibs

AEM Developerの皆さん、こんにちは、大和の蒲生です。

突然ですが、クイズです!

下記のClientlibsがあったとします。

f:id:yamato_tech:20200422174602j:plain:w300
各Clientlibsフォルダのプロパティ設定値は下記です。

/ale
- allowProxy Boolean = true
- categories String[] = brewery.ale
- dependencies String[] = brewery.lagar, brewery.pilsner
/lagar
- allowProxy Boolean = true
- categories String[] = brewery.lagar
/pilsner
- allowProxy Boolean = true
- categories String[] = brewery.pilsner
- embed String[] = brewery.stout
/stout
- allowProxy Boolean = true
- categories String[] = brewery.stout

下記のようなHTMLの場合、

<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html">
    <sly data-sly-call="${clientlib.css @ categories='brewery.ale'}"/>
</sly>

JSPであれば、

<ui:includeClientLib categories="brewery.ale" />

下記A~Eうち、どれがレンダリング結果として出力されるでしょうか?

A

<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/ale.css" type="text/css">

B

<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/ale.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/lagar.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/pilsner.css" type="text/css">

C

<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/lagar.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/stout.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/pilsner.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/ale.css" type="text/css">

D

<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/lagar.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/pilsner.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/brewery/clientlibs/ale.css" type="text/css">

E

<link rel="stylesheet" href="/apps/brewery/clientlibs/lagar.css" type="text/css">
<link rel="stylesheet" href="/apps/brewery/clientlibs/pilsner.css" type="text/css">
<link rel="stylesheet" href="/apps/brewery/clientlibs/ale.css" type="text/css">

答えは、、、、、ブログの一番最後にあります

というわけで、今回のテーマはクライアントライブラリのembeddependenciesのコンセプトについて、違いがよくわからなくて、難しいと感じていたので調べた内容を、ちょっと詳しくまとめていこうかなと思います。 奥深いクライアントライブラリの重要なコンセプトについてより知識を深めるためのキッカケになればうれしいです。

クライアントライブラリベーシック

クライアントライブラリとは

AEMの特徴の一つであるクライアントライブラリですが(Client LibraryとかClientlibsと呼びますが)、この機能によってクライアントサイドのライブラリフォルダを整理・管理することが可能です。 整理できるアセットはCSS・JS・画像・フォントなどです。 クライアントサイドのコードをレポジトリに格納でき、categoriesに分類することで、いつどのコードがクライアントサイドで読み込まれるべきか操作することができます。

クライアントライブラリ設定プロパティ

ここで、クライアントライブラリの設定について詳しく見ていきたいと思います。

1.categories

categoriesは設定したクライアントライブラリがどのカテゴリーに属するかを示す識別子です。categoriesはJSやCSSのカテゴリーを設定し、複数の値が設定可能です。1つのライブラリフォルダは1つ以上のcategoriesに属することができます。

2. dependencies

クライアントライブラリが依存する、他のクライアントライブラリのcategories一覧で、依存しているクライアントライブラリのcategories名を値として持ちます。 brewery.aleのファイルがbrewery.lagarに依存している場合、brewery.aledependenciesの値にbrewery.lagarが入っていないといけないです。

3. embed

他のクライアントライブラリに内包される場合に設定します。brewer.pilsnerbrewer.stoutのファイルが埋め込まれている場合、出力HTMLはbrewer.pilsnerのみですが読み込まれているファイルはbrewer.pilsnerbrewer.stoutが連結されたファイルになります。

4. allowProxy

/apps配下のクライアントライブラリーをproxyサーブレットを経由しての呼び出しを許可するプロパティです。 オーサーインスタンス上だと/apps配下もアクセスが可能ですが、パブリッシュインスタンスに公開してしまうと、/apps配下は404が返ってきてしまいますよね。そこで、このallowProxy Boolean = trueプロパティをクライアントライブラリに追加することで、scrのパスが/appsから/etc.clientlibs/配下に代わり、etc/を介したアクセスが可能になります。

embeddependenciesの違いは?

dependenciesの関係はあくまでも独立したライブラリどうしの関係

dependenciesの場合依存関係のあるファイルごとにインクルードとリクエストがされます。 下記の図のような依存関係がある場合、

f:id:yamato_tech:20200501100248p:plain:w350

HTML出力はこうなります。

<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/c.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/b.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/a.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/all.css" type="text/css">

embedはその名の通り埋め込まれる

dependenciesとは異なり、embedした場合、embedされたクライアントライブラリは内包されて呼び出されるんですね。

そのため下記の埋め込み関係の場合、

f:id:yamato_tech:20200501100518p:plain:w350

HTML出力は下記になります。

<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/all.css" type="text/css">

dependenciesembedミックススタイル

では、dependenciesembedが下記のように混ざり合ってる場合、HTML出力はどうなるでしょうか。

f:id:yamato_tech:20200501100551p:plain:w300

<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/c.css" type="text/css">
<link rel="stylesheet" href="/etc.clientlibs/myproject/clientlibs/all.css" type="text/css">

はい、もうお分かりですね。 依存関係のある、clientlibs.cと他のクライアントライブラリをembedしているclientlibs.allがHTML出力されます。

便利ツールたち

1. Dumplibs

https://[ホスト名]:[ポート番号]/libs/granite/ui/content/dumplibs.html

AEMにOOTBで入っているツールですが、categoriesを入力することでライブラリのdependenciesの検証も可能です。一貫性のないdependenciesembed設定を指摘してくれます。 他にも、categoriesを入力することで、全クライアントライブラリのパスを確認することができます。

2. Client Library Optimizer - ACS AEM Tools

このACS AEM ToolsのClient Library Optimizer(https://adobe-consulting-services.github.io/acs-aem-tools/features/clientlibs-optimizer/index.html)を利用すると、効率的なembed構造が分かっちゃいます。なんと便利なツールがあるんですね。 これを使えば初期に構成したクライアントライブラリの構成が変わった場合などに、dependenciesembedの最新で最適な構成がわかっちゃいます!これでCSSやJSが追加・削除された場合も、すべてのClientlibsを確認しなくても、Clientlibsの最適化ができます。

参考

Using Client-Side Libraries

AEM Client Libraries explained by example

A deep dive into AEM Clientlibs...

Client Libraries Interview Questions

AEM Clientlibs: Difference between Dependencies and Embed

Proxing clientlibs in AEM

クイズの答えはDです!皆さん当たりましたかね?

D以外の選択肢の間違っている箇所に少し解説を入れると、

選択肢A: brewery.aledependenciesが無視されてしまっているので、不正解。

選択肢B: 読み込み順番が間違っているので、不正解。

選択肢C: brewery.pilsnerembedが無視されてしまっているので、不正解。

選択肢E: すべてのクライアントライブラリのallowProxy Boolean = trueが無視されてしまっているので不正解。

ここまで読んでいただいてありがとうございました。またお会いする日まで~! Happy Coding