はじめに
こちらは バイセルテクノロジーズ 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 を作ってみました。こちらのコンポーネントは name
を prop
経由で受け取り、受け取った名前を表示するというだけの単純なコンポーネントです。
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 の技術に興味があり、これから一緒にコンポーネントの共通化を推進してくれるエンジニアを募集しています。少しでも気になった方はぜひご応募お待ちしています。
明日のバイセルテクノロジーズ Advent Calendar 2022 は稲川さんの「railsのscopeを使って関連テーブルを含め一括で取得した話」です、そちらもぜひ併せて読んでみてください!