マイクロフロントエンド(本)
https://gyazo.com/295d73c941080615e71108d248f5ef06
1章 フロントエンドのいま
かつて、Webアプリケーションは、従来の静的な企業Webサイトと区別して「リッチインターネットアプリケーション(RIA)」と呼ばれていた。
wintyo.icon 今だと「シンプルなWebサイト」と「リッチなWebアプリケーション」とかになるのかなぁ🤔 自分は「サイト」と「アプリケーション」で区別している。
wintyo.icon Web制作ともいうかも
この章では現在利用可能なアーキテクチャを分析する。
1.1 マイクロフロントエンドアプリケーション
マイクロサービスアーキテクチャに触発されて開発された新しいアーキテクチャ。
開発やデプロイに関わるスループットを低下させず、自立したチームに作業を分散させるという考えが基になっている
ビジネスロジックとコードの複雑さを大幅に削減すると、以下のオーバーヘッドを考慮する必要が出てくる
自動化
ガバナンス
観測性
コミュニケーション
机上では素晴らしいアーキテクチャはいくつもあるが、それは現実では上手くいかなかった
プロジェクトが構築される環境とそのコンテキスト(会社の構造、文化、開発者のスキル、タイムラインなど)を開発者が考慮しなかったため
システムを設計する組織は、必然的に、その組織のコミュニケーション構造のコピーである設計を生み出すことになる
マイクロフロントエンドは、マイクロサービスや全員が自身の領域に責任を持つという強力なエンジニアリング文化と組み合わせることで、組織のアジリティと市場投入までの時間を短縮できる可能性がある。
モノリスバックエンドやサービス指向アーキテクチャ(SOA)など、他のバックエンドアーキテクチャと組み合わせて使うことも可能だが、一番適しているのはマイクロサービスアーキテクチャ
1.2 シングルページアプリケーション
SPAではロジックをクライアントとバックエンドどっちに寄せるか決められる。
クロスプラットフォームをターゲットにするならロジックはバックエンドに寄っていた方が対応しやすい
オフライン対応が必要であればクライアントにロジックを寄せたいた方が良い
SEO観点のデメリットがある
SEOのインデックスを最適化したい場合は、クローラー専用のHTMLを返すのが一般的
組織面のデメリットもある
同じコードベースでチームが分割されていると、実装方法が異なってしまい、どれが正解か分からず混乱する可能性がある
会社の構造やアーキテクチャがそれを最善の方法で表現できず、仕事を遅らせ、外部依存を生み、新機能開発中に全体的に摩擦を発生させてしまう
1.3 アイソモーフィックアプリケーション
サーバとクライアント間でコードが共有され、両方のコンテキストで実行できるWebアプリケーション
wintyo.icon SSR的なやつ?
SSRの分量はプロジェクトの要件に応じて決める
初期表示用のデータも全てfetchしてレンダリングするパターン
複数のSPAに分割して一部だけサーバーサイドでレンダリングする混合パターン
wintyo.icon これがGatsbyで提唱されていた複数のSPAか
スケーラビリティの問題に悩まされる可能性がある
サーバー側でレンダリングするため、キャッシュ戦略をしっかり立てないとリクエストが多いとパフォーマンスに支障が出る
wintyo.icon SSRはこの辺の問題と、localStorageなどクライアント側でしかアクセスできないことを気をつけなきゃいけないのが面倒なんだよねぇ😔
1.4 静的ページのWebサイト
1.5 Jamstack
JavaScript
API
Markup
wintyo.icon Markupが入るからSSGを指すのか🤔 SPAも同じジャンルだと思ってた。。
メリット
CDNにより直接提供できるためパフォーマンスが良い
インフラとメンテナンスが安価
静的ファイルなため拡張性が高い
攻撃対象が少ないためセキュリティが高い
ヘッドレスCSMと簡単に統合できる
1.6 まとめ
2章 マイクロフロントエンドの原則
クラウドシステムによって以前よりもプロジェクトを簡単にスケールできるようになっているが、モノリスはシステムの一部分だけでなく、システム全体をスケールする必要がある
モノリスのコード開発が困難になるケース
中大規模なチームではコミュニケーションのオーバーヘッドが起きる
ほんの一握りの人間がチーム全体の決定を行うという集権的な意思決定
wintyo.icon むしろそれをするためのモノリスって感じな気がする
マイクロサービスアーキテクチャ
ユニークなコードベースを小さな部品に分割し、それぞれが機能のサブセットを持つ
コードがシンプルになり、チームの認知負荷が軽減される
マイクロサービスの落とし穴
分散システムを制御下に置くために、自動化、観測性、監視に対してリソースを割く必要がある
マイクロサービスの境界が間違って定義される
マイクロフロントエンドはビジネスや責任の境界に沿ってソフトウェアのデプロイを定義する新しいアプローチ
従って全てのソフトウェア分解に対する普遍的な答えではない
2.1 モノリスからマイクロサービスへ
新しいプロジェクトは、そのビジネスが成功するかどうかを理解するためなため最小限のシステム構成を作る
MVP(Minimum Viable Product、実用最小限のプロダクト)と呼ばれる
マイクロサービスを採用することは、
データベース戦略を見直すことでもあり、マイクロサービス間で共有されない複数のデータベースを持つことになる
各チームがマイクロサービスのセットに対して責任を負う
昔のフロントエンドでは、いくつかの理由からアプリケーションをスケーリングする選択肢があまりなかった
数年前までは全てのビジネスロジックをバックエンドが担当しており、フロントエンドも分割する必要性があまりなかった
wintyo.icon ということは今でもバックエンドに比重を置く構成であればコードを分割する必要があまりない?
フロントエンドのモノリスアプリケーションは今でも有効だが、問題もある
コードベースに適用されるルールは一度に決定されることが多く、数ヶ月から数年間はそのルールに縛られてしまう
ビジネスもテクノロジーと同じように、一定のペースで進化していくべきで、この状態は避けるべき
wintyo.icon 確かにモノリスは全体のリファクタはしづらいよなぁ
コードの抽象化も銀の弾丸ではない
再利用のために拙速にコードを抽象化しても、必要以上に複雑になった割に再利用されたのは2回だけみたいなケースがある
複数のプロジェクトやチームにまたがってライブラリを使用すると、コードベースがより複雑になったり、手動テストに多くの労力が必要になる
wintyo.icon とはいえコピペ祭りも微妙だし、その辺の匙加減は難しいよねぇ
アーキテクチャの改善が困難になる
いざやるとなると多額の先行投資が必要になる
2.2 マイクロサービスの原則
マイクロサービスの原則
ビジネスドメインのモデル化
ビジネスドメインを中心としたモデリングは、ドメイン駆動設計(DDD)で提示された重要な原則 自動化の文化
自律的に動くサービスであるため、各々が異なる環境へ自動でデプロイする文化であるべき
実装の詳細を隠す
他のマイクロサービスと連携を取る場合はカプセル化してAPIを提供する
ガバナンスの分散
技術的な意思決定をマイクロサービスごとにしてスピード感を上げる
独立デプロイ可能性
システム全体でデプロイや失敗時のロールバックに時間がかかるため、マイクロサービス単位でデプロイするべき
障害の分離
高い観測性
サービスが分割されていると、全体の動きが把握しづらくなるため、観測性を高める必要がある
これらの原則に従うには、会社の組織のあり方についても思考転換する必要がある
中央集権的なパラダイムから分散的なパラダイムに移行
部門横断的なチームがビジネスドメインをエンドツーエンドで所有できるようにする
2.3 マイクロフロントエンドに原則を適用する
ガバナンスの分散
チームの意思決定を分散させることで、多くのチームの要求を満たすために妥協を積み重ねた結果メリットが少なくなってしまうような画一的なアプローチからようやく脱却できる
各チームが独自の方向性を持つべきという意味ではなく、技術的なリーダーに集権的な決定権を持たせることなくチームが活動できるようにするだけ
wintyo.icon できれば各々で動けるようになって欲しいけどねぇ
障害の分離
SPAでは問題なかったが、マイクロフロントエンドだとそうはいかない
複数ファイルでネットワーク障害が起きた時の404表示など
高い観測性
システム障害を完全に防ぐことに労力を費やすより、システム障害に対処する準備を整えておく方が重要
2.4 マイクロフロントエンドは銀の弾丸ではない
マイクロフロントエンドはその性質上、技術的・組織的なレベルで複雑さを増す可能性があるため、全てのアプリケーションに適しているわけではない
2.5 まとめ
3章 マイクロフロントエンドアーキテクチャとその課題
マイクロフロントエンドの背後にある原則
ビジネスドメインの表現
自律的なコードベース
独立したデプロイ
単一チームによる所有
マイクロフロントエンドには多くの選択がある
マイクロフロントエンド間のデータのやり取りをどうするか
別のビューにどのようにルーティングするか
マイクロフロントエンドのサイズをどのように分割するか
3.1 マイクロフロントエンドの意思決定フレームワーク
アーキテクチャ選定の上で重要な4つの項目
アーキテクチャにおけるマイクロフロントエンドの定義
水平分割
垂直分割
マイクロフロントエンドの構成
マイクロフロントエンドのルーティング
マイクロフロントエンド間のデータのやり取り
マイクロフロントエンドの定義
DDDには「コンテキストの境界」という重要な用語がある
ドメインとサブドメインによって定義されたビジネス領域を、以下に変換する
モデル
コード構造
潜在的なチームを定義する論理的領域
垂直分割マイクロフロントエンドを扱う場合、フロントエンドとバックエンドを同じ境界のコンテキスト内に簡単に一緒にマッピングできる
コンウェイの法則に則ってシステム設計をする企業が多くあるが、それは「システムを設計する組織は、その組織のコミュニケーション構造のコピーの設計を作成するように制限される」と言っているようなもの コンテキストの境界はできるだけ最後に決定する
ビジネスは時間の経過に従って変換するため、早く決めても変わってしまう可能性があるため
ECサイトのような静的なページは水平分割が適している
wintyo.icon レコメンド機能だけ切り出すとかができるからってこと?
マイクロフロントエンドの構成
クライアントサイドコンポジション
クライアント側で他のマイクロフロントエンドと結合する
エッジサイドコンポジション
CDNレベルでビューを組み立てる
サーバサイドコンポジション
サーバー側で全て組み立てるため、パフォーマンスの考慮が最も重要になる
マイクロフロントエンドのルーティング
サーバーサイドコンポジションの場合はオリジンでリクエストをルーティングするしかない
wintyo.icon これを避けるにはマイクロフロントエンドのSSR & CSRを考慮しないといけなくなるよねぇ
マイクロフロントエンドのコミュニケーション
原則自己完結であるが、認証情報など最低限必要な情報の連携手段
イベントエミッター
PubSub
Webストレージ
Cookie
クエリ文字列
3.2 マイクロフロントエンドの実践例
Zalando
HelloFresh
URLによってオーケストレーションされた多数のSPAを提供
AllegroTech
ページの構成方法と表示するコンポーネントとの間の追加抽象化が優れている
JSONファイル内で設定された通りにページを構成する
Spotify
デスクトップアプリケーション用に、C++で作成された低レベル実装のためのブリッジを介してやり取りするiframeがあった
SAP
SEOや帯域幅が問題とはならないB2Bソリューションなため、iframeを採用
OpenTable
Dockerレジストリに似たレジストリに、データとUIをカプセル化した利用可能な全てのコンポーネントを集約し、任意のHTMLテンプレートで利用できるカプセル化可能なHTMLフラグメントを公開
この手法によって米国で開発した部品をオーストラリアで再利用し、プロセスが円滑に進んだ
wintyo.icon ちょっと次元が違うなぁ。。
DAZN
BootstrapというクライアントサイドASTのジョンとによってオーケストレーションされたSPAとコンポーネントを組み合わせて使用
wintyo.icon BootstrapってUIフレームワークじゃないんだっけ?🤔
3.3 まとめ
4章 マイクロフロントエンドアーキテクチャの発見
4.1 マイクロフロントエンドの意思決定フレームワークの適用
垂直分割はSPAに最も近い開発者体験になる
水平分割に適する例
1つのビジネスサブドメインを複数のビューで表示する必要があり、サブドメインの再利用性が鍵となるプロジェクト
検索エンジンの最適化がプロジェクトの重要な要件であり、サーバーサイドのルーティングのアプローチを使用する場合
フロントエンドアプリケーションで数百人の開発者が一緒に作業する必要があり、より細かいサブドメインを分割しなければならない場合
wintyo.icon このユースケース正直よく分からないんだよなぁ。流石に開発者いすぎ・・・
特定の部分を顧客がカスタマイズするようなマルチテナントプロジェクトで上手く機能する場合
4.2 アーキテクチャ分析
分析ポイント
デプロイ可能性
モジュール性
簡素性
テスト容易性
パフォーマンス
開発者体験
スケーラビリティ
全体管理
完璧なアーキテクチャは存在せず、常にトレードオフの関係にあるため、最適なものを模索し続ける
ビジネス要件や組織構造もトレードオフに関係する
4.3 垂直分割アーキテクチャ
アプリケーションシェル(コンテナ的なやつ)にマイクロフロントエンドをロードする理由
ユーザの初期状態の処理
アプリケーション全体で使用される設定の取得
ロードを行うため利用できるルートと関連するマイクロフロントエンドを取得
ロギング、可観測性、マーケティングライブラリの設定
マイクロフロントエンドがロードできない場合のエラー処理
アプリケーションシェルを共有層としては使わない
多用すると分散モノリスのような状況になり、ロジックがカオスになる
課題
状態の共有
基本的にはWebストレージで問題ない
機密性が高いものはパブリックAPIから情報を取ってきてそれを各マイクロフロントエンドに流し込むやり方もある
クライアントサイドでマイクロフロントエンドを構成するテクニック
ESモジュール
SystemJS
モジュールフェデレーション
webpack5のプラグイン
外部モジュールやライブラリ、アプリケーション全体を別のモジュール内に読み込む際に使う
以下の観点をサポートして、普通のSPAを書いているかのような体験ができる
マイクロフロントエンドの範囲をラッピング
異なるマイクロフロントエンド間での依存関係の共有
同じライブラリの異なるバージョンを実行エラーなしに処理するための調整
HTMLのパース
マイクロフロントエンドであっても複数のフレームワークを使うことは推奨されない
パフォーマンスの問題と依存関係の衝突の危険性があるため
デザインシステムの位置付け
第一層、デザイントークン
第二層、基本コンポーネント
第三層、UIコンポーネント
第四層、Mircro Front-end
SEO対策
クローラーにインデックス可能な方法でアプリケーションコードを最適化する
5秒以内にDOMを構築する
クローラーがコンテンツを抽出して適切に分類できるようなHTMLを返す
ダイナミックレンダリングを使って最適化されたバージョンのWebアプリケーションを提供する
SSGのような事前にビルドしたHTMLをS3などにおいておく
Puppeteerなどで実際にアクセスしてみた結果のHTMLをS3などにおく
SPAは全部ダウンロードするが、垂直分割のマイクロフロントエンドだと必要な部分だけ読み込む
wintyo.icon これよくメリットで挙げられるけど、SPAもdynamic importにすることでページ単位のimportはできるんだよね。。
共通ライブラリをvendor側に入れるか個々で担うか
vendor側に入れると根底のバージョンが変わった時のアップデートが大変
個々だと毎回ロードする必要になる
利用可能なフレームワーク
モジュールフェデレーション
table:垂直分割のスコアリング
アーキテクチャ特性 スコア
デプロイ可能性 5/5
モジュール性 2/5
簡素性 4/5
テスト容易性 4/5
パフォーマンス 4/5
開発者体験 4/5
スケーラビリティ 5/5
全体管理 4/5
4.4 水平分割アーキテクチャ
同じ画面に複数のマイクロフロントエンドが入るため、最も難しい実装
CSSクラスの解決方法でBEMにプレフィックスつける案が挙がる
wintyo.icon CSS Modulesじゃダメなの?w
マルチフレームワーク戦略が許される唯一のタイミングは、レガシーアプリケーションを新しいアプリケーションに移行する時のみ
wintyo.icon 折角独立して動かすんだからバラバラでもいい気がするけどなぁ。確かにパフォーマンス観点で無駄なライブラリを読み込むハメになるけど、新しい技術を試せる場にもなるから、状況に応じて選択しても良い気はする。そうしないといつまでも同じフレームワークを使い続けるハメになってフットワーク重そうに見えるけどなぁ
wintyo.icon って思っていたけど、よくよく考えてみたら試してみてそれを放置するわけにもいかないからほぼリプレイスするか取り下げるかのどちらかにはしたくなるか。
モジュールフェデレーション
JSコードのチャンクを同期または非同期でロードできる。
さまざまなマイクロフロントエンドやデザインシステムといった共有ライブラリをシンプルな方法で非同期的に統合できる
バージョンが同一の場合はvendor.jsにまとめられ、異なる場合は衝突しないように上手くラップする
table:webpackのモジュールフェデレーションを使った際のスコアリング
アーキテクチャ特性 スコア
デプロイ可能性 4/5
モジュール性 4/5
簡素性 5/5
テスト容易性 4/5
パフォーマンス 4/5
開発者体験 5/5
スケーラビリティ 5/5
全体管理 3/5
wintyo.icon 全体的にモジュールフェデレーションは最高だけど、webpack限定という制約が気になるところ。ビルドツールはVite, turbopackなど技術革新が起こっている中で従来のwebpackに縛られる方針は少し怖いところ
iframe
デメリット
全体のサイズ把握が困難なのでレスポンシブの実装は不向き
検索エンジンによるインデックス付けができない
table:iframeを使った際のスコアリング
アーキテクチャの特徴 スコア
デプロイ可能性 5/5
モジュール性 3/5
簡素性 3/5
テスト容易性 3/5
パフォーマンス 2/5
開発者体験 3/5
スケーラビリティ 5/5
全体管理 3/5
Webコンポーネント
WebコンポーネントはSvelteやLitElementからコンパイルできる
Webコンポーネントにすることで互換性の問題を解消して共通UIコンポーネントとして提供できる
wintyo.icon その発想はなかった・・・
wintyo.icon 面白いアイデアだけど、型が分からないからやっぱり今のままで良いかも。。
wintyo.icon ReactはWeb Componentsを出力できなそう。
SEO対策では、Shadow DOMだと中が見れないので、コンポーネント内部もHTMLとして表示しておくLight DOMにしておいた方が良い
code:html
<my-account-mfe>
<h2>Welcome to My Account</h2>
</my-account-mfe>
table:Webコンポーネントを使った際のスコアリング
アーキテクチャ特性 スコア
デプロイ可能性 4/5
モジュール性 3/5
簡素性 4/5
テスト容易性 4/5
パフォーマンス 4/5
開発者体験 4/5
スケーラビリティ 5/5
全体管理 3/5
サーバーサイド
利用可能なフレームワーク
wintyo.icon 結構あるね。。
table:サーバーサイドコンポジションのスコアリング
アーキテクチャ特性 スコア
デプロイ可能性 4/5
モジュール性 5/5
簡素性 3/5
テスト容易性 4/5
パフォーマンス 5/5
開発者体験 3/5
スケーラビリティ 3/5
全体管理 3/5
エッジサイド
ESIで実装
デメリット
全てのCDNプロバイダやリバースプロキシに対応していない
動的コンテンツに対応できない
table:エッジサイドコンポジションのスコアリング
アーキテクチャ特性 スコア
デプロイ可能性 3/5
モジュール性 4/5
簡素性 2/5
テスト容易性 3/5
パフォーマンス 3/5
開発者体験 2/5
スケーラビリティ 4/5
全体管理 3/5
4.5 まとめ
5章 マイクロフロントエンドの技術的実装
5.1 プロジェクト
今回のアーキテクチャ
マイクロフロントエンドを特定するハイブリットアプローチ
サブドメインに応じて水平分割、垂直分割をハイブリットに扱う
クライアントサイドコンポジション
クライアントサイドのルーティング
Webストレージ、イベントエミッターでデータ共有
5.2 モジュールフェデレーション入門
5.3 技術的実装
サンプルコード
wintyo.icon コードの説明を見る感じ、モジュールフェデレーションはライブラリコードが一緒であるほどvendor.jsに寄せられるから、モノレポにして比較的ライブラリに制約がかかっている状態になっていた方が扱いやすそうな気がしてきたなぁ🤔
5.4 プロジェクトの進化
レガシーなアプリケーションからマイクロフロントエンドに移行する場合は、レガシーアプリケーションをラップしたマイクロフロントエンドにしておくと柔軟性が上がる
5.5 webpackのロックイン
モジュールフェデレーションは現在はwebpackのみだが、高く評価されて、本番環境で使い始めている。
モジュールフェデレーションを使わない場合のリファクタのコストはどのくらいかを見積もって、その上でロックインするかを決めると良い
5.6 まとめ
特定の決定の背後にある理由を説明することは、それぞれの実装を評価するよりもずっと価値がある
wintyo.icon このくらいのレベルになると、思想とか文化とかが大事になってくるよねぇ
6章 マイクロフロントエンドの構築とデプロイ
マイクロサービスになるとインフラストラクチャの管理が大変になるため、Ci/CDに時間と労力を費やす必要がある
6.1 自動化の原則
以下3つは似ているが少し違う
継続的インテグレーション
継続的デリバリー
継続的デプロイ
自動化の速度と信頼性を担保するための原則
フィードバックループを高速に保つ
頻繁に繰り返し自動化戦略を強化する
チームがマイクロフロントエンドについて正しい決定を行えるように権限を与える
CI/CD全て特定の人だけが管理する状態は危ない
少なくとも、成果物をビルドするタスク部分は各チームで責任を持つ
ツールの標準化をメンテナンスしながら、チームがオペレーションや決定を行うためのガードレールと呼ばれる境界を見極める
堅牢なテスト戦略を定義する
特にエンドツーエンドのテストに時間を費やすのが不可欠
6.2 開発者体験
マイクロフロントエンドが増えてくる場合はスキャフォルディングを用意しておくと良い
wintyo.icon スキャフォルディングのメンテも必要になってしまうからなんとも言えないところだね。。もはやそれ用のフレームワークを用意した方がいいんじゃないかレベルな気がする。20個とかめちゃくちゃ数が多い場合に考慮する感じかなぁ。
6.3 バージョン管理
単一リポジトリ(モノリポ)
メリット
コードの再利用性
チーム間の協力が簡単
技術的負債が少なく、まとまりのあるコードベース
依存関係管理がシンプル
ライブラリをアップグレードする場合、そのライブラリを使用する全てのチームが協力してコードベースを更新し、技術的負債が蓄積されることを防ぐ
wintyo.icon 逆言えば全て更新しないと動かなくなっちゃうんだよねぇ。。
大規模なコードリファクタリングがしやすい
新入社員のためのオンボーディングがシンプル
デメリット
自動化ツールへの継続的な投資
コードベースが大きくなった時のスケーリングツール
プロジェクトは一緒に結合される
行儀の良い開発者
注意点
独立したデプロイ可能な成果物にならない可能性がある
GoogleやFacebookでも採用している
何年にもわたって、集中型リポジトリのスケーリングを保つために必要な投資が増えるにつれて、Googleのリーダーたちは、モノリシックモデルから移行すべきかどうかをしばしば検討した。しかしながら、Googleは中央リポジトリの方が利点が大きいと考え、中央リポジトリを繰り返し選択した。
ソースコード管理のモノリシックモデルは、すべての人に適しているわけではない。オープンで協調的な文化を持つGoogleのような組織に最適だ。コードベースの大部分がプライベートであるか、グループ間で隠されている組織ではうまく機能しない。
wintyo.icon オープンにしたいならモノレポの方が良いのかもなぁ。邪魔ならそのディレクトリを見なければ良いだけだし。マルチリポにすると確かに仕組み上隠れてしまい、それが他プロジェクトに手を出しづらくさせることになるのか。
複数リポジトリ(マルチリポ or ポリリポ)
メリット
プロジェクトごとに異なるブランチ戦略を採用できる
他のチームをブロックするリスクがない
プロジェクト間の相互関係としての契約について考えることを強く推奨される
wintyo.icon これメリットなの?
きめ細かいアクセス制御
ツールへの先行投資と長期投資を削減
デメリット
プロジェクトが発見しにくい
コードの重複
注意点
リポジトリの命名規則
メンテナンスのベストプラクティス
サブドメイン単位の複数リポジトリというハイブリット構成もある
6.4 継続的インテグレーション管理
エンドツーエンドテストを技術的に正常に実装する方法
すべてのマイクロフロントエンドが存在する本番環境やステージングですべてのエンドツーエンドを実行する
シナリオテストに必要なすべてのリソースをまとめるオンデマンド環境を用いる
担当するマイクロフロントエンドをエンドツーエンドテストを実行するときにプロキシサーバを用いてテスト対象を切り替える
wintyo.icon モック的な扱いにするのか
適応度関数。これで評価して品質を維持し続ける
バンドルサイズ
パフォーマンスメトリクス
静的解析
コードカバレッジ
テストが広範囲に行われているか
セキュリティ
6.5 デプロイ戦略
ブルーグリーンデプロイ
テストが通ったらすべて最新バージョンにリダイレクトする
カナリアリリース
テストが通っても一部のユーザだけ最新バージョンにリダイレクトする
table:カナリアリリースとブルーグリーンデプロイで利用できるルーターオプション
ブルーグリーンデプロイまたはカナリアリリースのメカニズム
クライアントサイドルーティング アプリケーションシェル、静的なJSONとバックエンドAPIによって渡される設定
エッジサイドルーティング エッジで実行されるロジック(例: AWS Lambda@Edge)
サーバーサイドルーティング アプリケーションサーバロジック、APIゲートウェイ、ロードバランサー
wintyo.icon クライアントサイドでもできることが驚き
ストラングラーフィグパターン
アプリケーションの一部を置き換えて徐々に移行するパターン
6.6 まとめ
7章 事例: マイクロフロントエンドのための自動化パイプライン
7.1 状況設定
自動化戦略の6つの領域
バージョン管理
モノレポであるためLernaを採用
wintyo.icon yarn workspacesでもモノレポ管理はできるよね。パッと調べた感じだとLernaは一括でnpm publishする機能もあるっぽい
パイプライン初期化
コード品質のレビュー
ビルド
ビルド後のレビュー
デプロイ
マイクロフロントエンドの自動化戦略は、SPAで使用されている従来の戦略と大きく変わらない
7.2 まとめ
8章 マイクロフロントエンド用のバックエンドパターン
8.1 APIの実装とマイクロフロントエンド
APIのパターン
サービスディクショナリ
クライアントが利用可能なサービスの単なるリスト
APIゲートウェイ
一つのドメインで複数のマイクロサービスをまとめる
機能一覧
トークンバリデーション
可視性とレポート
レートリミット
BFFパターンもこのカテゴリに属する
複数のマイクロフロントエンド間で共有するための、クライアントサイドのAPIエンドポイントライブラリを作成するかもしれないが、おすすめはしない
一部のライブラリバージョンに古いライブラリバージョンを埋め込んでしまう可能性がある
wintyo.icon axiosでfetchするコードを共通化する話ってこと?別にpeerDependenciesにしておけばそこまで問題にならない気がするけどなぁ
wintyo.icon まぁどのみちコードは別々で書いて良い気はする
サービスディクショナリを使う
例
code:json
{
"my_amazing_api": {
},
"my_super_awesome_api": {
}
}
各APIのバージョンリストを用意することで、各々のクライアントで必要なバージョンを指定して動かすことができる。
2枚のピザのチームの人数構成だと、全体を把握しきれないため、段階的に移行できる仕組みが必要。 API層を進化させ続けるには、マイクロサービスへの完全な移行を行うのではなく、モジュラーモノリスに移行するだけで十分なケースもある
wintyo.icon これはマイクロフロントエンドでも同じことが言える気がする。わざわざ成果物まで分割していなくても、モノリシック内である程度モジュール化してコードを隠蔽できる構成になっていればマイクロフロントエンドまでしなくても良いケースはありそう
水平分割の場合はサービスディクショナリの管理はアプリケーションシェルで行う
マイクロフロントエンド側でやると各々がリクエストを投げてしまってパフォーマンスに影響が出るため
データの渡し方
windowオブジェクトを介す
ReactだとContext API経由でサービスディクショナリを渡す
APIゲートウェイを使う
メリット
複数のマイクロサービスを一元管理できる
デメリット
APIゲートウェイに障害が起きると全て動かなくなる
耐障害性を高めるには、APIゲートウェイのクラスターが必要
運用コスト
APIゲートウェイでAPIを追加、変更、削除するためのルールを徹底する
APIゲートウェイを差し込んだことによるオーバーヘッド
ビジネスドメインごとに1つのAPIエントリポイントを実装するパターンもある
障害の影響範囲をビジネスドメイン単位で済む
ビジネスドメイン単位でカスタマイズ可能
BFFパターンを使う
BFFの方が良いケース
API層がWebとモバイルアプリケーションの両方で読み込まれるケース
wintyo.icon Webアプリだけだったらクライアント側でパーサー書いても良いと思っていたけど、確かに他のプラットフォームも考慮する場合はBFFあった方が良いね
モバイルだと非表示になるデータがある場合はそれも考慮したBFFになっていると尚良い
水平分割とBFFは相性が悪い
水平分割のマイクロフロントエンドは独立性を意識するためどのドメインに属するかを直接持たせたくないため、仕組みが複雑になる
wintyo.icon でもこれあくまでサブドメイン単位で分割したい場合であって、全部1つのBFFにまとめる場合は問題ないよね
垂直分割の場合はマイクロフロントエンドとドメインは1対1で紐づいているので楽
マイクロフロントエンドでGraphQLを使う
GraphQLでバージョン管理したい場合はエンドポイント自体を分ける
GraphQLで全スキーマを全てのチームが触るとコンフリクトが発生しやすい
スキーマフェデレーションを使ってそれぞれでスキーマを定義することができる
ただし、GraphQLはUIを念頭に置いて設計する必要があるため、組織間で連携が必要
ベストプラクティス
複数のマイクロフロントエンドで同一のAPIを使用している場合、マイクロフロントエンドの境界を再検討した方が良い
APIの仕様をまず定義してから実装
APIファーストの原則を採用する
APIの一貫性
エラー処理などのAPIの仕様を標準化する
WebSocketとマイクロフロントエンド
WebSocketはマイクロフロントエンド単位で生成せず、アプリケーション全体で1つ作成し、そのソケットを各マイクロフロントエンドに渡す
マイクロフロントエンドをロード中にイベントが来た場合は、バッファを用意してためておく
こうすることでロード後にそのイベントも読み取ることができる
1つのマイクロフロントエンドにしかWebSocketが使われない前提であればマイクロフロントエンド内で閉じても良い
適切なサブドメインに対する適切なアプローチ
クロスプラットフォームアプリケーション用のAPIの設計
ポーリング値などのパラメータをBFFに仕込んでおいて本番環境でパラメータをいじれるようにすると柔軟性が上がる
8.2 まとめ
マイクロフロントエンドはマイクロサービスだけでなくモノリシックアーキテクチャにも適している
wintyo.icon まぁBFF導入したら表側の構成はマイクロサービスみたくできるしね
9章 事例: モノリスからマイクロフロントエンドへ
9.1 コンテキスト
9.2 マイグレーション戦略
9.3 実装の詳細
マイクロフロントエンドで気をつける点
アプリケーションシェルの責務
並行して行われるマイクロサービスへの移行を考慮したAPIとの統合
認証機構の実装
マイクロフロントエンド間の依存関係の管理
複数のマイクロフロントエンドでのコンポーネントの共通化
ユーザ体験におけるデザインの一貫性の導入
フロントエンドのカナリアリリース
ローカライゼーション
共通ライブラリが最新かどうかCIでチェックする
古い場合はCIを落とすことで最新状態を保てる
9.4 まとめ
プロジェクトの成功をつなぎ合わせる要素は非常に多い
各人のスキル
環境
文化
10章 組織にマイクロフロントエンドを導入する
アーキテクチャに大幅に変更を加える際に検討すること
コミュニケーションフローを整理する方法
ビジネスドメイン内で正しい決定を下せるようにする方法
10.1 なぜマイクロフロントエンドを使うのか
10.2 組織とソフトウェアアーキテクチャの関連
コミュニケーションが粗いのか細かいのかでチーム構成を検討すると良い
分散チームのように粗い場合はコードも分けてしまった方がメリットになるケースが多い
ユーザジャーニーごとにサブドメインをグループ化する
ただし、ユーザジャーニーでは完全に分割はできない
10.3 コミュニケーションの流れをスムーズにするガバナンスの実装
table:RFCのテンプレート
セクション 説明
機能名 導入または変更する機能またはプラクティスの名前
概要 機能または実践の短い説明
動機 なぜそれを行うかという理由
変更に対する説明 変更または新機能の詳細な分析
欠点 提案者提出者によって特定された全ての潜在的な問題
代替案 調書と短所で目標を達成するための潜在的な代替案
未解決の質問 提案の資格となるような未解決の問題
追加のリソース RFCに関連するリソースのリスト
現在または将来の開発者の意思決定のコンテキストを共有するためのドキュメント
主にアーキテクチャに関する話
table:ARDのテンプレート
セクション 説明
ステータス ドラフトや合意済みと行ったADRの状態
関係者 アーキテクトや技術リーダーといったADRに関連する人
結論 最終的な決定事項
期限 決定を下さなければならない日付
オーナー このドキュメントの所有者
イントロダクション 会社の状況とADRが解決しようとしている問題の説明の要約
フォース アーキテクチャの変更に向けて推進している並行または重複する作業の流れ
選択肢 ビジネスと技術の詳細、および全ての提案の長所と短所を含む潜在的なソリューションのリスト
最終決定とその論拠 選択肢の中から選択した決定事項と、その論拠
付録 多くのコンテキストを提供するために必要な追加の資料
10.4 コミュニケーションの流れを良くするテクニック
知識を広げていくための要素
定期的に導入した技術についての共有会を開いたりなどする
10.5 分散された組織
マイクロフロントエンドに分割する際に注意する点
データに基づいて分割する
チームをサブドメインに割り当てるときに複雑さのバランスをとる
複雑さの高いサブドメイン
更に細かく分割する
初期に多くの労力を必要とするサブドメイン
wintyo.icon これの対応がよくわからない😔
通常の複雑さのサブドメイン
コンポーネントとして切り出すパターンがある
複雑さの低いサブドメイン
マイクロフロントエンドの構築と保守が簡単なものは複数持っても良い
ただし、コンテキストスイッチのコストは発生することに注意
10.6 まとめ
付録 開発者インタビュー: マイクロフロントエンドとの向き合い方
ニミシャ・アスタギリ: edXチーフアーキテクト
マイクロフロントエンド関連のOSSプロジェクト
フェリペ・ギザール: Wizeline シニアソフトウェアエンジニア
マイクロフロントエンド関連のOSSプロジェクト
アンソニー・フレナー: フロントエンドアーキテクト
マイクロフロントエンド関連のOSSプロジェクト
ジョエル・デニング: フロントエンドソフトウェア開発者、独立コンサルタント
マイクロフロントエンドサンプルリポジトリ
マイクロフロントエンドでおすすめなツール
import-map-overrides
single-spa
import-map-deployer
Import Maps
SystemJS
ザック・ジャクソン: Lululemon プリンシパルエンジニア
エリック・グライゼン: ソフトウェアエンジニア
デザインシステムは1つのチームで管理した方が良い
みんなやれるようにしても、誰もやらないため、責任の所在があった方が進めやすい
デビット・ライトナー: SQUER Solutions 共同設立者
経験上、パフォーマンスに関してはマイクロフロントエンドアーキテクチャでパフォーマンスを追求すればするほど、実装をクライアントに寄せた方が良い
wintyo.icon これは意外。初期表示を早めるためにSSRとか言われているのに、それとは逆の回答だ
フィリップ・プラハト: SAPアーキテクト兼プロダクトオーナー
マイクロフロントエンド関連のOSSプロジェクト
コア機能のほとんどを試せるプレイグラウンド
/icons/hr.icon
所感
思っていたよりマイクロフロントエンドのフレームワークは多かった
軽くググったくらいでは全然情報が見つけられなかった。。
マイクロフロントエンドは個別でフレームワークを選定できることがメリットの一つだと思ったがそれは避けた方が良いことは驚き
結局統一していた方がvendor.jsにまとめることができ、パフォーマンスが良くなる
この状況だとyarn workspaceでモノレポ構成が一番良さそう
逆コンウェイ戦略という言葉があるように、アーキテクチャを導入する前に組織体制を調整・検討をする必要があって相当広い視野で考える必要がある
垂直分割はシンプルな管理サイトでは導入しやすく、ビルドパフォーマンスの観点だけでいうと分割しておくことにメリットはありそう
ただし、最近はViteなど高速でビルドできるためそこまでメリットはないかも