こんにちは。SmartMat Cloud(以下 SMC) のフロントエンドチームの@hiroki_hayashi と申します。 現在、SMC に蓄積した消費データを分析できるレポート機能を開発中です。 今回のレポート機能から MicroFrontend 化とそれに伴う技術選定、アーキテクチャ設計を行いましたので開発途中ではありますが、選定理由と現在開発を行っている所感について書いていこうと思います。
現在、SMC は Vue.js/Nuxt.js の 2 系で実装されています。 TypeScript 化に伴って Nuxt.js の 2 系では this に依存する都合上、型補完の恩恵受けるためには限界がありました。 加えて、今回のレポート機能の要件は非常に難易度が高く、現在利用している UI コンポーネントやライブラリでは対応が難しく仕様やデザインが制限が生まれてしまいます。
後述する MicroFrontend の導入に伴って機能の一部を別の Repository に切り出すことで 技術選定の自由度が飛躍的に上昇しました。
MicroFrontend といっても対応内容は単純で、現在利用している Ambassador でルーティングを行うだけです。 当初懸念されていた認証認可についても同一ドメイン内でルーティングを行うことで比較ローコストで実現できました。
Frontend 側では、Repository を跨いだルーティングを行う場合は、フレームワークのルーティング機構を用いず、Location.href を利用するなどの対応が必要ですが、考慮することはそこまで多くない印象です。
とはいえ、今後 Repository が増えてきた場合に、環境変数や共通関数を npm モジュール化するといった必要性は感じています。
今回は TypeScript を中心に比較的オーソドックスな技術選定を行いました。
以下の 3 点を評価し採用しました。
TypeScript との相性はいわずもがなで tsx も純粋関数なのでハマりどころも少なくシンプルに実装できる印象です。 しかしシンプルが故にコード自体の記述量は多くなります。
Next.js はダイナミックルーティングの存在とメンテナンス性を考慮し選択しています。 要件上、SSR/SSG は不要でしたが、CSR 対応を考慮しても選択するメリットがあったと感じています。
GraphQL は以下を期待して採用しています。
従来の SMC の開発の課題として API インターフェースのコミュニケーションコストの高さがありました。 バックエンドエンジニアが OpenAPI を定義し、それを元にフロントエンドが手動で型定義、インターフェースの実装を行うという状態で、OpenAPI の恩恵を受けられていない状態でした。
今回の開発ではバックエンドが GraphQL schema を定義しフロントエンドがそれをローカルで sync しつつ query を書きます。 そこから graphql-codegen を用いて型定義を自動で生成します。
codegen コマンドを叩いた際に、自動で schema の sync が行われ、query も補完が効くので開発体験が大幅に向上しており不要なコミュニケーションをなくすことができました。
BFF との疎通はすべて GraphQL を用いて行っており、GraphQL client には Apollo を採用しています。 非常に多機能かつ、シンプルな実装になるため今のところ開発につまることはなく、スムーズに実装ができています。 後述する状態管理も Apollo の Reactive variables を用いて行っています。
Apollo client の Reactive variables を用いて状態管理を行っています。 加えて、useReactiveVar を用いてよりシンプルに実装しています。
Setter/Getter を定義し、他の状態管理の思想を踏襲する形で実装しています。
Bulma を利用しています。 選定理由としては別 Repository では Bulma をベースにした UI コンポーネントを利用しており、デザイン的な整合性をとる必要がありました。 加えて、デザイン的な要件が高い実装だったので柔軟性を考慮しUI コンポーネントではなく CSS フレームワークをあえて採用しています。
CSS フレームワークを採用している都合上、基本的にはスタイルレスの ライブラリを採用し、スタイル及び class を上書きする形でデザイン要件を実現しています。 多数採用していますが、特筆すべきライブラリのみ抜粋しご紹介します。
グラフ描画ライブラリです。 描画したい要素のコンポーネントを追加していくという非常な直感的な実装に加え、ドキュメントも非常に充実しています。
軽量かつ拡張性が非常に高く採用にいたりました。 HTML を拡張する形で実装が可能です。 そのため、bulmaとの親和性、その他状態管理との相性もよく、カラムの表示/非表示などの state 管理やそれを sync する機構も用意されており、非常に取り回しが良い印象です。
開発中ということもあり、内容が限定されてしまいましたが、いかがだったでしょうか。 アーキテクチャの話や運用していく中で、今回の技術選定の振り返りについて今後このブログで触れていきたいと思います。