Web Components 元年 v6

meguro.es #29
saku🌸 / @sakupi01

saku

🤗

Web Frontend Engineer
@Cybozu

🍏 / ☕ / 🌏 > ❤

Web Components 元年 v6

2024~2025

Implementations

Declarative Shadow DOM

  • 🔥 2024 Newly Available: DSD(Declarative Shadow DOM)
    • Shadow DOMをDeclarativeに作成できるようになった
    • SSR対応へ一歩前進した
  • 2024 Newly Available: setHTMLUnsafe, parseHTMLUnsafe
    • 動的にDSDを追加するためのメソッドも生えた
<host-element>
  <template shadowrootmode="open">
    <slot></slot>
  </template>
  <h2>Light content</h2>
</host-element>

Scoped Custom Registries

import {OtherElement} from './my-element.js';
// CustomElementRegistry instanceを生成してCEを登録
const registry = new CustomElementRegistry();
registry.define('other-element', OtherElement);
export class MyElement extends HTMLElement {
  constructor() {
    this.attachShadow({mode: 'open', registry});
  }
}

Reference Target for Cross-root ARIA

  • 🔥 Experiment: Reference Target for Cross-root ARIA
    • IDREF-IDの参照関係を、Shadow DOMのカプセル化を保ちつつできるように
      • 今までShadow DOMに対してARIA Linkを作れなかった
    • Light DOMとShadow DOM間でARIAが動作するように
<input
  role="combobox"
  aria-controls="fancy-listbox"
  aria-activedescendant="fancy-listbox"
/>
<fancy-listbox id="fancy-listbox">
  <template
    shadowrootmode="open"
    shadowrootreferencetarget="real-listbox"
    shadowrootreferencetargetmap="aria-activedescendant: option-2"
  >
    <div id="real-listbox" role="listbox">
      <div id="option-1" role="option">Option 1</div>
      <div id="option-2" role="option">Option 2</div>
    </div>
  </template>
</fancy-listbox>

Others

Hot Topics & Discussions

Shadow RootへCSSをDeclarativeにimportしたい①

  • 🔥 Declarative CSS Module Scripts
    • JSランドでは(Constructable StyleSheet+CSS import assertion + adoptedStyleSheets)の合わせ技があるけど、それをDeclarativeにやる方法が欲しい!せっかくDSDできるようになったんだし!
<!-- 宣言的にConstructable StyleSheetを作成し、 -->
<!-- module specifier(.css) をimport assertionの代わりに使い、 -->
<script type="css-module" specifier="/foo.css">
  #content {
    color: red;
  }
</script>
<script type="css-module" specifier="/bar.css">
  #content {
    font-family: sans-serif;
  }
</script>
<my-element>
  <!-- adoptedstylesheets属性でadoptedStyleSheetsの代わりをすることで読み込む -->
  <template shadowrootmode="open" adoptedstylesheets="/foo.css, /bar.css">
    <!-- ... -->
  </template>
</my-element>

Shadow RootへCSSをDeclarativeにimportしたい②

  • 🔥 @sheet
    • 複数のStyleSheetをまとめて一つにする方法がほしい(ネイティブバンドル)
    • ついでにStyleSheet毎に読み込めるメカニズムもつけて
@sheet foo {
  div {
    color: red;
  }
}

@sheet bar {
  div {
    font-family: sans-serif;
  }
}

div {
  color: blue;
}
<template shadowrootmode="open">
  <style>
    /* The following two imports should only make a single network request. */
    @import "sheet.css#foo";
    @import "sheet.css#bar";
  </style>
  <!-- ... -->
</template>

HTMLをimportできるようにしたい

  • 🔥 HTML Module Scripts
    • HTML Importsはダメだったけど、HTMLをimportできる仕組みは引き続き欲しい
    • これが来ると、Import Attributes風にHTMLをimportできるようになる
    • 部分的なDeclarative Custom Elementsも可能になる?
    • Declarative CSS Module Scriptsが実現すれば、それの手法を活用して、HMTL Module ScriptsもDeclarativeにできるかも?(ref)

--- JSON Module ScriptsはInterop 2025 Focus Areasのひとつ

ビルトイン要素の拡張がしたい

Ecosystems & Concept Shifts

Ecosystems & Concept Shifts

The Open UI Design System by Open UIとWeb Components

The Open UI Design System by Open UIとWeb Components

これまでのDesign Systemレイヤー GDSによって補完されたDesign Systemレイヤー
  • W3Cのイチ組織で検討された、堅牢で柔軟なWCsライブラリを提供
  • 競合する標準の作成はしない
  • HTMLと各デザインシステムとのギャップを補完する新しいレイヤーとなる
    • 組織のデザインシステムやOSSのデザインシステムでもなければ、Headless UIと重複するものでもない
  • HTMLの拡張レイヤー的な位置付け

🎄Open UI Advent Calendar: Day 23 / Global Design System Part1, 🎄Open UI Advent Calendar: Day 24 / Global Design System Part2

Web Awesome by Font AwesomeとWeb Components

  • 2024/04; Web Awesome
    • ShoelaceというFont Awesome製のWeb Componentsライブラリの後継が立ち上がる
  • 2024/09; TAGのLea Verou, 11tyのZach Leathermanが参画
    • 標準側へのエスカレーションやOSS/リアルワールドユーザからのFBを発展させる体制が整っていそう
  • 現状OSSではなく、ソースコードを公開しない営利目的のプロジェクト
    • W3C管轄で非営利のThe Open UI Design Systemとの明確な差分の一つ
  • W3Cじゃないけど、The Open UI Design Systemと似たような思想で似たようなことをやっていきそう
    • The Open UI Design Systemとの連携は?
    • 開発速度や認知でOpen UIとどう変わってくるのか?
    • そもそも目指すところの差分はあるのか?
  • 2025年初頭にローンチ予定

Ecosystems & Concept Shifts

1. WCs primarily benefit from
Generalizable Elements

... because they're interoperable and painful.

Web Componentsと効果のグラフ
  • 一般性とWCsの旨みは比例。WCsを使うのは簡単だが、作るのは簡単じゃない
    • 技術的にはもちろんだが、一般性が増すほど厳格なSpecやテストが必要になる
  • 消費者が多い一般性の高い要素に対するWCsの作成は、トレードオフとして許容範囲
    • WCs消費者が作成者の量を凌駕する場合、WCsが効果的に使われているとも言える
  • 極端な例だと、ネイティブ要素がC++で実装されてても誰も何も言わない
Web Componentsと効果のグラフ
  • それならブラウザネイティブ要素にしてしまえばいいのでは?
    • 標準化は意図して低速
      • Selectの拡張に「5年」かかった。拡張したい要素はまだまだある
    • 標準化前段で高速なイテレーションを回すレイヤーが必要
      • それが発展して標準化に貢献できる可能性もある
    • そのレイヤー(Generalizable Elements)にこそ、WCsが使われるべき

リソースが無限にあるなら、HTML要素として存在しても問題ない要素に対してWCsは効果的

2. Web Components don’t do everything Framework Components do

... so, stop fighting each other and comparing!

Frameworks vs Web Components ... なのか?

  • エコシステム(FW)は新しい方法論をtry-and-errorする場。FWが標準の進化を促進してきた場面も多い
    • jQuery→document.querySelector()、SaSS→CSS Custom Properties、JSX→Tagged template literals、Preact→Signals
  • Component-Based Frameworks→WCs
  • WCsはFWが担うこと全てをやるわけではない&標準がエコシステム(try-and-errorの場)のやること全てを担うことは不可能。WCsはFWからの移行先ではない
    • importしてきたものを、templateで複製し、SDをattachして、CEとしてdefineしたものを使い回す以上のことをFWはやる
    • WCsはその過程を手助けする手法を提供する
    • なので、FWとWCsは互いに補完し合う関係にあるべき
  • ただ、FWがWCsと互換性があるわけではない
    • FWは元からWebの機能に追従できるように設計されているとは限らない
  • エコシステムと標準は 逆らう 手を取り合うことで前に進んできた。WCsに至ってもそうあるべき

WCsはReactでもなければ、Svelteでもなく、Vueのコンポーネントでもない。

JSX vs Web Components ... なのか?

  • JSXの解決したいこととWCsの解決したいことは根本的に違う
    • WCs: 十分にGeneralで、消費者が作成者よりも圧倒的に多くなるコンポーネント/要素に対して効力がある
    • JSX: WCsがカバーしない領域で、(WCsを利用しつつ)機能する
    • WCsを用いて開発することは多くの人に頻繁に起こり得るが、WCsを開発することは一部に限定されていて良い
    • 「JSX over WCs || WCs over JSX」ではなく、「WCs in JSX」という構図が望ましい

WCsはJSXの代替にならない/なることを意図されてデザインされていないし、その逆も然り

デフォルトの見た目

Wrap Up

2024年のWeb Componentsの評価

今年の評価ですが、

  • 低レベルAPIを揃える議論で大きな進捗を見せることができました
    • まだまだ「difficult→easy」ではなく、WCsの利用を「impossible→possible」にする機能をそろえる段階
  • これまでに例を見なかった、WCsを取り巻く環境の変化を見ることができました
    • Open UI, Web Awesomeなど
    • そこから浮き彫りになる、WCsの概念やユースケースの確立

2025年のWeb Componentsに期待すること

  • 引き続き、低レベルAPIの整備を頑張ってほしいです
  • WCsを取り巻くエコシステムが標準化にどう拍車をかけるのか、WCsのユースケースやカバー領域がどう定義づけられていくのか

来年は元年v1(2016)から10年

Thank you!

Appendix

```html // とか、このcontentをCEのshadowRootにそのままappendChildしたり <script type="module"> import {content} from "foo.html" with {type: "html"}; document.body.appendChild(content); </script> // ===== // DSDで書かれている中身のHTMLを`import.meta.document`HTML Module documentとして取ってきて、CEに流用できる <template id="myCustomElementTemplate"> <div>...</div> </template> <script type="module"> let importDoc = import.meta.document; class myCustomElement extends HTMLElement { constructor() { super(); let shadowRoot = this.attachShadow({ mode: "open" }); let template = importDoc.getElementById("myCustomElementTemplate"); shadowRoot.appendChild(template.content.cloneNode(true)); } } customElements.define("myCustomElement", myCustomElement); </script> ```

## Others - [Revamped Scoped Custom Element Registries](https://github.com/whatwg/html/issues/10854) - DOM Parts - Style and Theme APIs - open-stylable / `::theme` / exporting parts - `:has-slotted` / `\slot\` - ... ---