この記事は Angular Advent Calendar 2020 の 16 日目の記事です。
はじめに
最近、レガシーなフロントエンド環境を採用したプロジェクトで開発をする機会があり、これまで制作したAngularコンポーネントを再利用するため、Angular Elementsを使用してみました。
Angular Elementsの導入はとても簡単でうまくいったのですが、その過程でWeb ComponentsにおけるコンポーネントやCSSの設計に悩まされることが多かったので、それについて調べたり考えたことをまとめてみようと思います。
Angular Elements とは
Angular Elementsは、AngularのコンポーネントをCustom Elementsに変換する機能です。
Custom Elementsに変換されたコンポーネントは独自のHTML要素として定義され、フレームワークに依存せず通常のHTML要素のように扱うことができます。
<!-- 独自のHTML要素 -->
<my-elem></my-elem>
<!-- Custom Elementsの読み込み -->
<script src="my-elem.js"></script>
コンポーネントの@Input
はHTML要素の属性、@Output
はHTML要素のイベントとして定義されます。
注意点として@Input
から定義される属性名には、元のプロパティ名をケバブケースに変換したものが使用されます。
また、それらの属性に渡した値はすべて文字列として扱われます。
文字列でない値を渡したい場合は、JavaScriptで取得した要素のプロパティから値を渡す必要があります。
<!-- 属性の値の代入 -->
<my-elem my-string="Hello, world!"></my-elem>
<script>
const myElem = document.querySelector('my-elem');
// @Inputプロパティの値の代入
myElem.myNumber = 123;
myElem.myArray = ['a', 'b', 'c'];
// @Outputイベントのハンドリング
myElem.addEventListener('myEvent', (e) => {
console.log(e);
});
</script>
CSSのカスタマイズ
コンポーネントに適用したスタイルは、もちろんCustom Elementsとして表示される際も適用されます。
しかし、Custom Elementsを表示するページのデザインに合わせてカスタマイズしたいケースも多くあると思います。
今回は適用したスタイルが直感的にCustom Elements全体に反映されるように、以下のように意識してみました。
- Custom Elementsの内部で使用されているコンポーネントに適用するスタイルを最小限にする
-
font-size
などサイズの指定にできるだけem
や%
を使用する
よりカスタマイズ性を高めるには、CSS Variablesによるカスタマイズ用のCSS変数の定義や、要素内部のDOMツリーを追ってスタイルを適用するといった方法があるようです。
Custom Elementsの粒度
今回はすでに制作してあるコンポーネントで、サービスの使用が前提になっていたため、使いたい部分を1つのコンポーネントでラップしてCustom Elementsを作成しました。
その結果1つのウィジェットとして目的を達成することができましたが、変更が容易でなく、使用するアプリケーション側からすると汎用性に欠ける、モノリシックなCustom Elementsになってしまったような気がします。
Custom ElementsはAtomic DesignでいうところのAtomsからMoleculesぐらいのまでの粒度で作成し、それらとビジネスロジックを組み合わせて機能を実装していくようなイメージなのかなと思いました。
Custom Elementsに限った話ではなく、普段からコンポーネント設計に向き合っていくことが重要だと再認識させられました。