Web Components

Web Componentsとは



Web Componentsは、HTML要素をコンポーネント化するための技術群の総称であり、それらを用いて作成されたコンポーネントそのものを指します。従来のウェブ開発では、1つの巨大なHTMLファイルと全体に適用されるCSSが一般的でしたが、Web Componentsは「再利用可能なコンポーネント群の組み合わせ」という新しいアプローチを可能にしました。このアプローチは、カスタム要素、Shadow DOM、HTMLテンプレートという3つの主要な技術要素によって実現されています。これらの技術はWeb標準であり、主要なブラウザすべてでサポートされています。

背景



従来のHTMLは、単一のHTMLファイルで構成され、CSSはHTML全体に適用されていました。この方式では、HTMLを別の場所で再利用することが難しく、巨大なHTMLに対してCSSを管理するのが困難でした。プログラミング言語における関数やクラスのように、再利用可能なまとまり(コンポーネント)を作成する仕組みが強く求められていました。

技術



Web Componentsは、上記の問題を解決するために、以下の3つの主要な技術を用いています。

1. カスタム要素: 再利用可能なコンポーネントとしてカスタムHTML要素を定義することを可能にします。これにより、開発者は独自のHTMLタグを作成し、特定の機能や表示をカプセル化できます。
2. Shadow DOM: CSSの適用範囲とJavaScriptのアクセス範囲を限定し、独立したコンポーネント化を実現します。これにより、コンポーネントの内部スタイルやスクリプトが他の部分に影響を与えたり、外部からの影響を受けたりすることを防ぎ、コンポーネントの独立性を高めます。
3. HTMLテンプレート: HTML要素群のテンプレート化を可能にし(`template`要素)、インスタンスへの要素注入を可能にします(`slot`要素)。これにより、HTMLの構造をテンプレートとして定義し、必要に応じて動的に要素を挿入できます。

これらの技術を組み合わせることで、HTML要素のまとまりを作り出し、CSSやJavaScriptを含めてコンポーネントを隔離できます。さらに、コンポーネントを利用する際に`slot`要素へ適切な要素を挿入することで、引数を用いた関数呼び出しやクラスのインスタンス化のように、コンポーネントの振る舞いを柔軟に変更できます。

attribute-propertyリフレクション



HTML要素には、属性(content attributes)とプロパティ(IDL attributes)がありますが、これらは必ずしも値が連動するわけではありません。Web Componentsにおいて、いわゆるリフレクション(属性とプロパティの値を同期させる)を実現するためには、追加の仕組みが必要です。属性はすべて文字列として定義されており、プロパティは暗示的に静的な型を持つため、プロパティの型を事前に定義し、属性へのアクセス時に適切な型変換(文字列化や定義された型へのparse)を行うのが基本的な方法です。

特徴



カスタム要素


カスタム要素には、自律カスタム要素とカスタマイズされた組み込み要素の2種類があります。

自律カスタム要素: ネイティブのHTML要素とは完全に独立したカスタムHTML要素で、Custom Elements APIを用いてボトムアップで構築されます。
カスタマイズされた組み込み要素: ネイティブのHTML要素を基に構築され、元の機能を再利用できます。

Shadow DOM


Shadow DOMは、ブラウザがDOM要素をメインのDOMツリーに追加せずにレンダリングできる機能です。これにより、開発者とブラウザがアクセスできる範囲に境界線を作ることができます。開発者はネストされた要素と同様にはShadow DOMにアクセスできなくなりますが、ブラウザはネストされた要素と同様の方法でレンダリングとコードの修正が可能です。CSSを特定の要素のShadow DOM内にスコープすることで、HTML要素のカプセル化を可能にし、CSSスタイルが意図しない影響を他の要素に与えるのを防ぎます。これらの要素はHTMLとCSSに関してカプセル化されていますが、document内の他の要素が受け取るイベントを発火できます。要素内のスコープされたサブツリーはshadow treeと呼ばれ、shadow treeがアタッチされた要素はshadow hostと呼ばれます。Shadow DOMは、リテラル要素としてアタッチするか、またはスクリプトを使用して、常に既存の要素と接続されていなければなりません。JavaScriptでは、Shadow DOMは`Element.attachShadow()`を使用してアタッチします。Shadow DOMは、カスタム要素を作成する上で不可欠な要素です。もしShadow DOMがなければ、外部のカスタム要素が望まない方法で相互作用する可能性を排除できません。

HTMLテンプレート


HTMLテンプレートは、封印されたHTMLのチャンクを自由に挿入する手段です。テンプレート内のスクリプトは実行されず、リソースもテンプレートが実際に使用されるまでフェッチされません。

実装



Web Componentsの技術はすべてWeb標準であり、主要ブラウザでサポートされています。実装方法はユーティリティライブラリを含め様々です。

カスタム要素: `customElements.define(elemName, elemClass)`でグローバルな`customElements`に登録します。第2引数にはHTMLElementを継承したクラスを指定します。LitElementライブラリのTypeScript Decorator `@customElement(elemName)`は、`customElements.define()`の糖衣構文です。
Shadow DOM: `Element.attachShadow()`でShadow DOMを作成し、返り値の`shadow root`に要素を追加していきます。LitElementクラスは、暗黙的にShadow DOMをrootとします。
テンプレート要素: HTML内で`