LitではじめるWeb Components開発

「Web Componentsって独自のHTMLタグをつくれるんだよねー」くらいの認識で、これまで使ったことはありませんでした。この記事では、サンプルデータをつくって分かった事や、今後の課題について書きます。
Web Componentsは多くのブラウザがデフォルトで備えてる仕組みです。技術の概要を知りたい場合は[MDN](https://developer.mozilla.org/ja/docs/Web/Web_Components)をお読みください。構成する３つの技術（カスタム要素、Shadow DOM、HTMLテンプレート）や作り方の流れが分かります。

[Lit](https://lit.dev/)を使用します。Polymer、lit-elementに連なるライブラリで、Web Componentsが扱いやすくなります。[2021年9月にLit2.0がリリースされました](https://lit.dev/blog/2021-09-21-announcing-lit-2/)。

# 基本

このような独自タグを使うことができます。名称にはハイフンが必要です。

```html
<my-comoponents></my-components>
```

中身の実装には、TypeScript（JavaScript）のClassを使用します。
TypeScriptを使用すると [Decorators](https://lit.dev/docs/components/decorators/) を使うことができ、より簡潔に記述できます。

```typescript
import {LitElement, css, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';

@customElement('my-components')
export class MyComponents extends LitElement {
  static styles = css`
    :host {
      color: red;
    }
  `;

  @property()
  name?: string = 'World';

  render() {
    return html`<p>Hello, ${this.name}!</p>`;
  }
}
```

[LitのPlayground](https://lit.dev/playground/)を触れば、より理解できると思います。

# 開発環境を用意する

Litのスターターは[Modern Web の Web Dev Server](https://modern-web.dev/docs/dev-server/overview/)を使用してます。

- [Litのスターター](https://github.com/lit/lit-element-starter-ts)
- [Modern WebのLitサンプル　](https://github.com/modernweb-dev/example-projects/tree/master/lit-element-ts-esbuild)

Web Dev Serverは簡単にbuildlessな開発環境がつくれるのですが、プロダクションbuildは自分で書かなくてはいけません。面倒だなぁーっと思ってたら、ViteのサイトにWeb Dev Serverとの[比較](https://ja.vitejs.dev/guide/comparisons.html#web-dev-server)を見つけました。Viteにはビルドが用意されてます。
今回は[ViteのLit TypeScriptスターター](https://github.com/vitejs/vite/tree/main/packages/create-vite)を使用することにしました。Viteもbundleしないビルドツールです。Web Dev Serverと同じくesbuild、Rollupを使用しています。

サンプルデータ「playing-cards」の環境を作ります。

```terminal
npm init vite@latest playing-cards --template lit-ts

npm cd playing-cards
npm install
npm run dev
```

build設定を少し書き換えます。デフォルト設定はライブラリモードになっているので、不要な記述を削除、outDirとbaseを指定します。baseの設定はGitHub Pagesで公開するためのものです。

```tsx
export default defineConfig({
	base: '/playing_cards/',
  build: {
    outDir: '../docs',
    // lib: {
    //   entry: 'src/my-element.ts',
    //   formats: ['es']
    // },
    // rollupOptions: {
    //   external: /^lit/
    // }
  },
});
```

buildしたファイルの確認用にpackage.jsonのscriptsにpreviewを追加します。

```json
"scripts": {
  "preview": "vite preview --port 8080"
},
```

```terminal
npm run build
...
npm run preview
```

# サンプルデータの紹介

いくつか機能を使ったサンプルをつくりました。トランプのカードを絞り込むメニューです。
![ymnkx.github.io_playing_cards_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163452/a3f30248-be0b-a12b-f69b-04f176a23748.png)

https://ymnkx.github.io/playing_cards/

https://github.com/ymnkx/playing_cards

# 最後に

今後の課題と感想です。

- 新しいCSS設計を考える必要がある。
    - ShadowDOMでスコープが閉じる事や、カスタムプロパティの管理、構造と装飾の分離などを考慮する。
    - [食べログのCSS規約](https://note.com/tabelog_frontend/n/n2541778b81e3)が参考になる。ルール厳しい…
- Sassの今後を考える。[Viteのお勧め](https://ja.vitejs.dev/guide/features.html#css-%E3%83%97%E3%83%AA%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5)が良さそう。PostCSSでCSSの先取りする。
- 11tyでページ生成を管理してみたら良い感じだった。積極的に取り入れたい。
- Web Componentsを使ってるサイト（[任天堂の英語サイト](https://www.nintendo.com/)等）を見て学ぶ。
- コンポーネントを綺麗に再利用できるのは、すごく便利。

以上です。