バイセル Tech Blog

バイセル Tech Blogは株式会社BuySell Technologiesのエンジニア達が知見・発見を共有する技術ブログです。

バイセル Tech Blog

WebComponentで始めるUIコンポーネントの共通化

はじめに

こちらは バイセルテクノロジーズ Advent Calendar 2022 の 8日目の記事です。 前日の記事は 市田さんの「デプロイ頻度を上げるためにやったこと」でした。

こんにちは。バイセルテクノロジーズ、テクノロジー戦略本部に所属している藤井です。普段はリユースプラットフォームのフロントエンド開発をしています。

リユースプラットフォームは、買取、査定、在庫管理、出品管理など、商品の買取から販売までを一気通貫しておこなうためのものです。前述の通り、リユースプラットフォーム上には様々なアプリケーションが存在し、類似したコンポーネントが複数のアプリケーションで量産されてしまっているという事業課題がありました。

様々な選択肢を考慮した結果、WebComponent を導入する方向で検討を進めています。今回は、WebComponent の導入を検討している背景や、技術調査で分かったことを紹介したいと思います!

WebComponent を導入しようとした経緯

異なる FW 間でコンポーネントが再利用できる

前述した通り、現在弊社ではリユースプラットフォームを開発中です。リユースプラットフォーム上のアプリケーションは React が採用されていますが、現在稼働中の販売や買取を主るアプリケーションは Vue で実装されているという背景がありました。そこで特定のフレームワークに依存しない方法でコンポーネントを共通化したいという思いがありました。

新しい FW へスムーズに移行できる

フロントエンドはトレンドの移り変わりが激しいので、新しいフレームワークに乗り換える際もスムーズに移行したいという思いがありました。WebComponent は Web 標準の技術として利用ができるため、JS フレームワークのトレンドの変化に比べると、比較的長く利用できる技術であるという期待がありました。

WebComponent とは

WebComponent は、Web 標準の技術として再利用可能なコンポーネントを作成することを可能にします。普段 React や Vue で作成しているコンポーネントと同じような書き心地でコンポーネントの実装ができます。WebComponent は以下のような特徴があります。

Web 標準の技術としてカスタムタグが利用できる

React や Vue などのモダンなフレームワークで馴染み深いカスタムタグを Web 標準の技術として利用できます。カスタムタグは複数の箇所で再利用できます。

カプセル化されている

Shadow DOM の存在により、外側の DOM と分離されます。外部のスタイルの影響を受けることがありません。

ブラウザサポート

モダンなブラウザは全て WebComponent をサポートしています。polyfill も提供されているので、古いブラウザでサポートが必要な場合でも問題なく導入することが可能です。

WebComponent の導入

starter kit としてOpen Web Component を利用しました。Open Web Component は次のような開発に必要なツールを一通り提供しています。内部では LitElement と呼ばれるライブラリが使われています。

  • Testing
  • Demoing
  • Building
  • Lingting

LitEelment とは

Google によって作られた、Polymer の後継プロジェクトとして誕生したのが LitElement です。WebComponent ベースでコンポーネントを実装する際に使われるライブラリです。Web 標準の API を直接利用した場合と比べて以下のような特徴があります。

シンプルに記述できる

シンプルな記述で実装が可能というのが LitElement の特徴です。ブラウザネイティブの低レベルな API を使った実装では、記述量が多くなって、コード全体が複雑になってしまいますが、LitElement を使うことでシンプルな記述が実現できます。

データバインディングの機能を提供

LitElement ではデータバインディングの機能が提供されており、モダンなフレームワークと似たような開発体験を得られる点も特筆しています。また、WebComponent 標準の仕様として、Vue や React と似たようなライフサイクルフックが利用できます。

軽量なライブラリ

圧縮された状態で 5KB 程度なので、パフォーマンス観点でも問題にならない程度のサイズとなっています。

豊富なドキュメント

LitElement はドキュメントも充実しており、公式で提供している Playground を利用することで手軽に LitElement に触れることができます。 こちらで WebComponent に関するさまざまな情報を得ることができます。WebComponent で作られたパッケージの一覧も公開されているので、目的に沿ったものをここから見つけるのも良いかもしれません。

WebComponent をつくってみた

簡単な WebComponent を作ってみました。こちらのコンポーネントは nameprop 経由で受け取り、受け取った名前を表示するというだけの単純なコンポーネントです。

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

@customElement('my-component')
export class MyComponent extends LitElement {
  static styles = css`p { color: blue }`; // ①

  @property()
  name?: string = 'Unknown'; // ②

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

①. Shadow dom は外部のスタイルに影響を与えない

②. Props 経由でデータを受け取ることが可能

③. render 関数の中で HTML をレンダリング

そして、TypeScript がサポートされている点が魅力的です。

<my-component name="buysell" />

そしてカスタムタグをどこからでも利用できます。見ていただいてわかる通り、モダンなフレームワークを使ったコンポーネントの実装と大差ないことがお分かりいただけると思います。

まとめ

今回は LitElement について紹介させていただきました。WebComponent について興味のある方にとって、少しでも参考になれば幸いです。

今後は、今回作った WebComponent を複数のプロジェクトで利用可能にするために、NPM モジュール化する予定です。NPM モージュールをバージョニングすることで、WebComponent の更新が必要になった場合でも、利用者側が適切なタイミングで、モジュールを更新できるような仕組みにしていく予定です。

また、弊社では複数のアプリケーションを抱えている背景から、各アプリケーションでデザインの一貫性を保つために、WebComponent ベースのデザインシステムを作っていきたいという野望があります。

バイセルでは WebComponent の技術に興味があり、これから一緒にコンポーネントの共通化を推進してくれるエンジニアを募集しています。少しでも気になった方はぜひご応募お待ちしています。

herp.careers

明日のバイセルテクノロジーズ Advent Calendar 2022 は稲川さんの「railsのscopeを使って関連テーブルを含め一括で取得した話」です、そちらもぜひ併せて読んでみてください!