本セッションの登壇者
セッション動画
スライド
では、始めたいと思います。
まず自己紹介ですが、私はlacolacoと申します。AngularのGoogle公認エキスパートをやっております。あとはAngularの日本ユーザー会というコミュニティをやっております。最近Discordを始めたので、もしAngularに興味があったりAngularを使っている場合はぜひ遊びに来てください。
Classi Corp.というところで働いています。詳しいプロフィールは g.dev/lacoから見れます。
今日お話しするのは、まずWeb Componentsについて前提知識を話しておくということと、Angular Elementsという機能について、そして最近できるようになったAngular Elements周りの新しいアプローチ「Standalone Components」についてお話ししたいと思っています。
あらためてWeb Componentsとは
まず最初はWeb Componentsです。
数年前から言われている概念なので「もう知ってるよ」という人も多いと思いますが、あらためてどう位置付けられているかというと、「再利用可能なカスタムHTMLを作成する仕組み/Web標準」です。
その要素としては次の3つの基本概念があります。
- Custom Elements (=カスタム要素)
- Shadow DOM
- Templates/Slots
ここで一番根幹になるのがCustom Elemets、カスタムのHTMLのタグを定義して登録するという機能です。Shadow DOMとTemplates/SlotsはそのCustom Elementsをどのように作るかという(Custom Elementsに)付随する仕様みたいな位置付けなので、基本的にはCustom ElementsだけでもWeb Componentsにすることができると思っています。
今日話すのは基本的にCustom Elementsの部分だけです。
Custom Elementsが使える環境
Web標準の話をすると、必ず「それってどのブラウザで使えるの?」となると思いますが、2022年現在、Web Components周りの仕様はすべてグリーンです。IE11もサポートが切れ、この表から消えたことで、すべてStableとなっています。
なので、Web ComponentsをProductionで使うときに、基本的にこの辺りのブラウザであれば障壁はないと言えるんじゃないでしょうか。
また、使っているライブラリが対応しているかどうかがわからない場合には、Custom Elements Everywhereというサイトが便利です。自分が使っているライブラリやフレームワークがCustom Elementsを使う側になっても大丈夫かということを見られます。これを見てもらうとわかるんですが、ほとんどのフレームワークやライブラリから併用できます。なのでCustom Elementsに準拠して作られたカスタム要素はいろんなところで使えるという環境はもうすでにあると言えます。
APIはシンプルです。まず、HTMLElementを拡張したクラスを作ります。この場合、 MyElement
というクラスを作って、それが extends HTMLElement
になります。その作ったクラスをタグ名とセットで customElements.define()
という関数に渡すだけです。これで my-element
というタグをHTML中に設置すると、その要素は「MyElement」要素として振る舞うようになります。その先で、何か描画したり、イベントを出したりするのはクラスの内部で自由にできます。
とりあえず、ブラウザはタグ名を認識して、それに対応するクラスを初期化してくれるというのがCustom Elements APIです。
Angular Elements - Custom Elementsをビルドする
ここまでがWebの話です。このCustom Elementsをどうやって作るのかというと、まずひとつは先ほどのサンプルコードのように、直接HTMLElementを拡張したクラスを宣言すればよいです。生のJSでできます。ライブラリを使うことも当然できます。Custom Elementsを作ることに特化した、あるいは作りやすくなっているライブラリもあります。GoogleメインでメンテナンスされているLit、StencilというOSSだったり、ほかにもいろいろあります。
Custom Elementsを作ることにフォーカスしたライブラリもありますし、各種Componentライブラリが持っているComponent SystemをCustom Elementsに変換するというアプローチもあります。これはたしかVueにもありますし、Angularにもあります。AngularのコンポーネントをCustom Elementsに変換する - 今回お話しするのは、このAngularの部分で、Angular Elementsと言われています。
(Angular Elementsは)こんな感じのAPIです。
まず普通にAngularのコンポーネントを作ります。そのコンポーネントを createCustomElement()
という関数に渡すと、HTMLElementを継承したクラスにコンバートされるので、それをdefineします。1個手順が挟まったわけですね。元になるHTMLElemementを継承するクラスを、フレームワーク側が自動的に作ってくれるようになっています。
ユースケースですが、ひとつはコンポーネントライブラリUIコンポーネントを提供するようなライブラリで、Angular向けには、Angular Nativeのコンポーネントを出しますが、Angularじゃないところでも使えるようにCustom Elementsとしても提供します。このようにユニバーサルな対応ができるというのが特徴です。
もうひとつはアプリケーションで使う機能です。これは、アプリケーションの一部を担っているコンポーネントをウィジェットのような形でCustom Elementsとして吐き出すと、それをAngularアプリではないアプリ(たとえばCMSで管理された静的サイト)で貼り付けられるようになります。
これを使う具体的なアプローチとして、私が2019年から、Web Componentを使ったレガシーなWebアプリを部分的に置き換えていくというリアルなユースケースを現在進行形でやっております。その話はまたいつかどこかでできたらと思います。
Standalone Componentをカスタム要素に変換する
次にStandalone Comonentについて話します。これはAngular 14(今年の春のリリース)でできるようになった、Angularのコンポーネント単体(1ファイル)で扱いやすくなったAPIです。
モノはというと、この @Component
の中に standalone: true
と書くだけなのですが、このコンポーネントに必要なものがすべてスタンドアロンで扱えるので、たとえば遅延ロードのようにコンポーネント単位でDynamic Importをしてレンダリングするときにはかなり使いやすいです。そのファイル単体で完結するようなものが作りやすくなります。
ここではこのStandalone Componentをカスタム要素に変換するとどうなるか、という話をしたいと思っています。
まずこの1個のStandalone Componentは基本的に1アプリケーションとして実行できます。レンダリングするイメージですね。コンポーネント単体をドカンとレンダリングすることができます。
これをCustom Elementsにしても同じことができます。Custom Elementsに変換して、タグ名にすることができるようになったのは最近です。ちょっと前までは、「@NgModule」みたいにいろいろあったんですけど簡単になりました。これはAngularを使ってる人向けのサンプルコードです。
さらに、次のバージョン(v14.2)ではもっと楽になって、 createApplication
というCustom Elementsの準備段階にするために作られたAPIがあって、これを使うと1個のコンポーネントをCustom Elementsにするのをこれだけのコードで終わります。
ちょっと関数化して elementify
みたいにすると、コンポーネントを受け取って、Custom Elementsにして返すという関数がけっこう書きやすくなります。
これを Single File Angular Element
とすると、この1ファイルでコンポーネント定義から、Custom Elementsとしての登録まで全部終わって、これだけの行数で終わったね! みたいな感じです。これが、現在のAngular Elementsの現状です。
今日のお話はAngular Elementsは初めての人にも、ちょっと前に触って複雑だなぁと思った人にも見てもらえたらうれしいなと思います。スライドにデモを貼っているので、よかったら見てください。
以上です。ご清聴ありがとうございました。