paint-brush
マイクロフロントエンドの移行への旅 - パート 1: 設計@isharafeev
1,323 測定値
1,323 測定値

マイクロフロントエンドの移行への旅 - パート 1: 設計

Ildar Sharafeev13m2023/07/12
Read on Terminal Reader

長すぎる; 読むには

マイクロフロントエンド アーキテクチャへの移行には、組織構造と運用基盤の点で多大な投資が必要でした。代わりに、遅延読み込み (動的インポート) を活用する分散モノリス アーキテクチャから始めることをお勧めします。コードベースを、異なるチームが管理する異なる所有権領域に分割することが不可欠となるでしょう。
featured image - マイクロフロントエンドの移行への旅 - パート 1: 設計
Ildar Sharafeev HackerNoon profile picture

今日のペースの速いデジタル世界では、俊敏性と拡張性が重要であり、企業は Web アプリケーションのパフォーマンスと保守性を向上させる方法を常に模索しています。


これらの目標を達成するための一般的なアプローチの 1 つは、モノリシック アーキテクチャから分散アーキテクチャ (またはマイクロ フロントエンド) への移行です。この記事シリーズ「マイクロフロントエンド移行の旅」では、AWS 勤務中にそのような移行を行った私の個人的な経験を共有します。


免責事項: 始める前に、この記事は私の個人的な経験を共有していますが、AWS やその他の組織のツール、テクノロジー、または特定のプロセスの専有的または内部的な詳細を開示することはできないことに注意することが重要です。


私は法的義務を尊重し、この記事がマイクロフロントエンドの移行プロセスに関わる一般的な概念と戦略のみに焦点を当てることに全力で取り組んでいます。


その目的は、機密情報を漏らすことなく、より幅広い状況に適用できる洞察と教訓を提供することです。

移住の動機

私は (皆さんと同じように) Martin Fowler のブログの記事からマイクロ フロントエンドについて学びました。フレームワークに依存しない方法でマイクロ フロントエンド アーキテクチャを構成するさまざまな方法を紹介しました。


この問題をさらに深く掘り下げていくと、既存のモノリシック アーキテクチャがチームの生産性にとって重大なボトルネックとなり、アプリケーションの全体的なパフォーマンスを妨げていることがわかりました。


私が移行を検討するようになった主な要因の 1 つは、アプリケーションのバンドル サイズの増加でした。


2020 年の夏に徹底的なバンドル分析を実施した結果、2019 年初めの最初のリリース以来、バンドル サイズ (gzip 圧縮済み) が 450 KB から 800 KB (解析されたサイズはほぼ 4 MB) に増加し、元のサイズのほぼ 2 倍になっていることがわかりました。


私たちのサービスの成功と継続的な成長の予測を考慮すると、この傾向が今後も持続し、アプリケーションのパフォーマンスと保守性にさらに影響を与えることは明らかでした。


私はマイクロフロントエンドの概念に熱中していましたが、次のような特定の課題に直面したため、まだマイクロフロントエンドを採用する準備ができていないことも認識していました。


  1. 小規模な組織構造: 私の分析時点では、私たちの組織は比較的小規模で、チーム内でフルタイムのフロントエンド エンジニアは私だけでした。マイクロフロントエンド アーキテクチャへの移行には、組織構造と運用基盤の点で多大な投資が必要でした。


    分散アーキテクチャを効果的に処理し、異なるフロントエンド コンポーネント間の依存関係を反映できる成熟した構造を持つことが重要でした。


  2. 限られたビジネス ドメイン: マイクロ フロントエンドは、限定されたコンテキストとビジネス機能に基づいて分割できますが (詳細については、「マイクロ フロントエンド アーキテクチャにおけるドメイン駆動設計」の投稿を参照してください)、当社の中核となるビジネス ドメインは、完全に分離することを正当化できるほど広範ではありませんでした。複数のマイクロフロントエンド。ただし、アプリケーション内には、分散アーキテクチャを切り開いて移行することが合理的な目に見える境界がありました。


これらのことを考慮すると、段階的なアプローチが必要であると感じました。マイクロフロントエンドへの完全な移行ではなく、分散アーキテクチャから恩恵を受ける可能性のあるアプリケーション内の特定の領域を特定することを目指しました。


これにより、組織構造全体を混乱させたり、ビジネス ドメインの完全性を損なったりすることなく、パフォーマンスとスケーラビリティの問題に対処できるようになります。また、チームを成長させ、ビジネスの方向性を観察する時間も得られます。


mciro フロントエンド アーキテクチャのみを使用してアプリのパフォーマンス (バンドル サイズ) の問題に対処したい場合、それは最良のアイデアではない可能性があることに注意してください。代わりに、遅延読み込み (動的インポート) を活用する分散モノリス アーキテクチャから始めることをお勧めします。


さらに、マイクロ フロントエンド アーキテクチャにはベンダー チャンクに分割されない共有コードが含まれる可能性が非常に高く、それがアプリケーション バンドルに組み込まれることを考慮すると、マイクロ フロントエンド アーキテクチャよりもバンドル サイズの問題が適切に処理されると思います (これは、このような分散アーキテクチャの欠点の 1 つです。何を、いつ、どのように共有するかをトレードオフする必要があります)。


ただし、分散モノリス アーキテクチャはマイクロ フロントエンドほど拡張できません。組織が急速に成長すると、チームも同じペースで成長する可能性があります。


コードベースを、異なるチームが管理する異なる所有権領域に分割することが不可欠になります。


そして、各チームは他のチームから独立した独自のリリース サイクルを持つ必要があります。各チームは、コード ベースが純粋に自分たちのドメインに焦点を当て、高速に構築できることを高く評価します (コードの分離 -> 保守性の向上/保守するコードの削減)。ビルド -> テスト容易性の向上/維持および実行するテストの削減)。

開始

リーダーシップからのサポートを得るために、私は Web の重要な指標を含む包括的なパフォーマンス分析を網羅し、分散フロントエンドへの移行のさまざまな段階の概要を説明した説得力のある技術ビジョン ドキュメントを作成しました。


この移行の中間フェーズの 1 つは、コア サービスとウィジェットの間で S3 バケットや CDN などの共有インフラストラクチャを活用しながら、複数のモジュール/ウィジェットを遅延読み込み技術によって非同期に配信できる分散モノリス アーキテクチャを確立することでした。 。


前回の記事で概説したように、このタイプの文書の主な考え方は、目標が達成され、最大の問題が解決された後の将来の姿を説明することです。実行計画の問題ではありません!


それからほぼ 1 年が経ち、ついにマイクロ フロントエンドの移行計画を実行する時が来ました。新しいドメインへの拡張が差し迫っており、より大規模なチームを自由に使えるため、私たちは移行を実行するための十分な準備ができていました。


これは逃すわけにはいかない絶好のチャンスだと感じました。


結局のところ、モノリシック アーキテクチャに限定されたままであるということは、その限界と永遠に格闘することを意味することになります。


新しいドメインに拡張するための限られたタイムラインが触媒として機能し、短くて遅い反復ではなく、よりスケーラブルで保守可能なアーキテクチャをすぐに構築する方向に私たちを推進しました。


移行を実行し、同時に新しいドメインでの作業を処理するために、チームを 2 つの専用グループに分割しました。優先度の高い機能作業はより多くのリソースを必要とし、より速いペースで繰り返す必要がありました。


移行プロセスの整合性と包括的な理解を確保するには、移行の処理を専門に担当する小規模の専任チームを割り当てることが合理的です。


ただし、マイクロフロントエンドのコンセプトが成功することを最初に確認せずに、機能の作業を進めることはできませんでした。


リスクを軽減し、明確なロードマップを提供するには、正確な見積もりと徹底的なリスク評価を含む低レベルの設計文書を作成することが重要でした。このドキュメントは、移行に必要な手順と考慮事項の概要を示す青写真として機能します。


このプロセスにおける極めて重要なマイルストーンは、設計に従ってすべてのコンポーネントが正常に統合されたことを実証する概念実証の開発でした。


「Point of no return」という適切な名前が付けられたこのマイルストーンは、マイクロ フロントエンド アーキテクチャの実現可能性と有効性を検証することを目的としていました。


私は移行が成功するだろうと楽観視していましたが、不測の事態に備えておくことは不可欠でした。その結果、私は、当初のコンセプトで望ましい結果が得られなかった場合のバックアップ戦略として機能するプラン B を考案しました。


これには、特に枕に泣きながら寝るためにさらに 7 日間を追加の見積もりに割り当てることと、遅延読み込み (分散モノリスを覚えていますか?) を介して新しい機能モジュールのエントリをコアに接続するために数日を割り当てることが含まれていました。

デザイン

マイクロフロントエンドを設計する場合、通常、構成には 3 つのアプローチがあり、それぞれランタイム アプリの解決が行われる場所に焦点を当てています。これらのアプローチの利点は、相互に排他的ではなく、必要に応じて組み合わせることができることです。

サーバー側の構成

基本的なアイデアは、リバース プロキシ サーバーを利用してページごとにマイクロ フロントエンド バンドルを分割し、ルート URL に基づいてページのハード リロードを実行することです。

長所:

  • 実装が簡単


短所:

  • グローバル状態はマイクロフロントエンド アプリ間で同期されません。クライアント側でバックグラウンド操作を長時間実行していたので、これは明らかに避けるべき点でした。


    この操作の「キュー」のスナップショットをローカル ストレージに保存し、ハード リロード後にそこから読み取ることができると主張する人もいるかもしれませんが、セキュリティ上の理由により、これを実装することはできませんでした。


    これはグローバル状態の一例にすぎませんが、サイドナビ パネルの状態 (展開/折りたたみ)、トースト メッセージなど、グローバル状態がどのように見えるかを示す別の例を次に示します。


  • マイクロアプリ間を移動する際のハードリフレッシュは、顧客にとってあまり親切ではありません。 Service Worker を使用して共有 HTML をキャッシュする方法がありますが、維持がさらに複雑になります。


  • インフラストラクチャの追加の運用コストとメンテナンス コスト: 各マイクロ フロントエンド アプリのプロキシ サーバー (これは CDN から直接読み取れば回避できます)、複数のページで再利用できる共通の (ベンダー) 依存関係をデプロイするための個別のインフラストラクチャ、および適切なブラウザによってキャッシュされます。

端面構成

マイクロ フロントエンド構成へのもう 1 つのアプローチはエッジサイド構成です。これには、CDN などのエッジ層でマイクロ フロントエンドを結合することが含まれます。たとえば、Amazon CloudFront はLambda@Edge統合をサポートしており、共有 CDN を使用してマイクロフロントエンド コンテンツを読み取り、提供できるようになります。

長所:

  • 維持するインフラストラクチャの部分が少ない: プロキシ サーバーが不要で、マイクロアプリごとに個別の CDN が必要


  • サーバーレステクノロジーを使用した事実上無限のスケーリング


  • スタンドアロンのプロキシ サーバーと比較して遅延が改善される


短所:

  • コールドスタート時間が問題になる可能性がある


  • マルチリージョン (分離) インフラストラクチャが必要な場合、Lambda@Edge はすべての AWS リージョンでサポートされるわけではありません

クライアント側の構成

クライアント側構成は、サーバー実装から分離されたクライアント側マイクロ フロントエンド オーケストレーション技術を利用する、マイクロ フロントエンド アーキテクチャへの別のアプローチです。


このアーキテクチャの中心となるのは、次の役割を持つコンテナ (シェル) アプリケーションです。


  • 横断的な問題への対処: コンテナ アプリケーションは、一元的なアプリ レイアウト、サイト ナビゲーション、フッター、およびヘルプ パネルを処理します。横断的な懸念を持つマイクロ フロントエンドとの統合はイベント バスを通じて行われ、合成イベントはグローバル ウィンドウ スコープ内で送信および処理されます。


  • マイクロフロントエンドのオーケストレーション: コンテナー アプリは、アプリケーションの要件とユーザーの操作に基づいて、どのマイクロ フロントエンド バンドルをいつロードするかを決定します。


  • グローバルな依存関係の構成: コンテナー アプリは、React、SDK、UI ライブラリなどのすべてのグローバルな依存関係を構成し、マイクロ フロントエンド間で共有できる別個のバンドル (vendor.js) として公開します。


一般的な考え方は、各マイクロ フロントエンド バンドルが 2 種類のアセット ファイルを生成するということです。

  • {hash}/index.js: これはマイクロフロントエンド アプリケーションのエントリ ポイントとして機能し、ハッシュはビルド全体の一意の識別子を表します。


    ハッシュは、S3 バケット内の各バンドルのプレフィックス キーとして機能します。複数のエントリ ポイントが存在する可能性がありますが、ハッシュはすべてのエントリ ポイントで同じままであることに注意することが重要です。


  • manifest.json: これは、マイクロフロントエンド アプリケーションのすべてのエントリ ポイントへのパスが含まれるマニフェスト ファイルです。このファイルは常に S3 バケットのルートに残るため、コンテナはこのファイルを簡単に検出できます。


    変更の可観測性を高めるために、S3 バケットでこのファイルのバージョン管理を有効にすることをお勧めします。 Webpack を使用してプロジェクトを構築している場合は、面倒な作業をすべて行ってくれるWebpackManifestPluginを強くお勧めします。


コンテナーは、ステージとリージョンに基づくマイクロフロントエンド アセットのソース ドメイン URL (CDN オリジン) のみを認識します。最初のページの読み込み中に、コンテナーは各マイクロフロントエンド アプリケーションのマニフェスト ファイルをダウンロードします。


マニフェスト ファイルのサイズは小さく (約 100 バイト)、ページの読み込み時間への影響を回避し、1 つのコンテナー内に複数のマイクロ フロントエンドを集約する場合でも適切に拡張できます。積極的なキャッシュを防ぐために、ブラウザのキャッシュ ストレージ内でマニフェスト ファイルが不変であると考えることが重要です。


適切なオーケストレーション ライブラリを選択することが、この構成における最大の課題であり、次の章で説明します。

長所:

  • サーバー実装に依存しない: このアプローチは、特定のサーバー要件なしで実装できるため、使用されるバックエンド テクノロジに柔軟性が提供されます。上の図に示すように、サーバーがなくても可能です。


  • グローバル状態の保持: コンテナー (シェル) アプリを使用すると、マイクロ フロントエンド間の切り替え時にグローバル状態を維持できます。これにより、シームレスなユーザー エクスペリエンスが保証され、移行中にコンテキストが失われることが回避されます。


  • 分散型アプローチ: 各マイクロフロントエンドは、自身をブートストラップするためにブラウザにどのデータを送信するかを個別に決定できます。コンテナ アプリは明確に定義された契約に従うだけで、自律性とモジュール性が向上します。


  • シンプルなローカル セットアップ: 開発ニーズに基づいて、アセット ソースを運用 URL とローカル URL の間で簡単に調整できます。マニフェスト ファイルは、コンテナ アプリが必要なマイクロ フロントエンドを検出して読み込むのに役立ちます。開発者は、コンテナと作業中の特定のマイクロフロントエンドの実行のみに集中できます。


短所:

  • マニフェスト ファイルをフェッチするためのネットワーク ホップの増加: コンテナーはマイクロ フロントエンドごとにマニフェスト ファイルを取得する必要があるため、他の構成アプローチと比較して追加のネットワーク リクエストと潜在的な遅延が発生する可能性があります。これは、最初のページ読み込み時にすべてのマニフェストを事前に読み込むか、いくつかの事前読み込み手法を導入することで軽減できます。


  • 共通の契約への準拠: すべてのマイクロフロントエンドは、ビルドを生成するための共通の契約に従う必要があります。これは、マイクロフロントエンド間の一貫性を確保するための共有構成と標準化された開発実践を通じて促進できます (これについては次のパートで詳しく説明します)。

ハイブリッド構成

この章の前半で述べたように、これらの構成パターンはすべて、同じシェル アプリケーション内で混合して一致させることができます。以下にその例を示します。

おすすめ

最初は同種のアプローチから始めることをお勧めします。自分に合った構成パターンを選択し、それを中心にインフラストラクチャの構築を開始します。


私たちにとって、クライアント側の構成が最良の選択肢でしたが、将来的には、一部のリージョンをエッジ側のオーケストレーションに切り替えることを検討しました (Lambda@Edge の可用性に基づいて)。

オーケストレーション ライブラリの選択

マイクロ フロントエンド アーキテクチャでクライアント側の構成を実装する場合、適切なオーケストレーション ライブラリを選択することが重要な決定となります。


選択したライブラリは、コンテナ アプリケーション内のマイクロ フロントエンドの動的な読み込みと調整を管理する上で重要な役割を果たします。


人気のあるオーケストレーション ライブラリがいくつか存在し、それぞれに独自の長所と考慮事項があります。

シングルスパ

Single-spa は、マイクロ フロントエンド構成に対する柔軟で拡張可能なアプローチを提供する、広く採用されているオーケストレーション ライブラリです。これにより、開発者は複数のマイクロフロントエンドのロードとアンロードを調整するシェル アプリケーションを作成できます。


シングル SPA は、ライフサイクル イベントに対するきめ細かい制御を提供し、さまざまなフレームワークとテクノロジーをサポートします。


長所:

  • フレームワークに依存しない: ライブラリは、React、Angular、Vue.js などのさまざまなフロントエンド フレームワークとうまく連携します。


  • 柔軟な構成: ルーティング、遅延読み込み、共有依存関係のための強力な構成オプションを提供します。


  • 堅牢なエコシステム: Single-SPA にはアクティブなコミュニティと、プラグインと拡張機能の豊富なエコシステムがあります。


短所:

  • 学習曲線: シングルスパを使い始めるには、その概念と API についての初期学習と理解が必要な場合があります。


  • カスタマイズの複雑さ: マイクロフロントエンド アーキテクチャが複雑になるにつれて、オーケストレーションの構成と管理が困難になる可能性があります。

乾君

Qiankunは、Ant Financial (Alibaba) チームによって開発された強力なオーケストレーション ライブラリです。構成には部分的な HTML アプローチが使用されます。マイクロフロントエンド アプリ側では、読み込まれるすべてのエントリ ポイントを含むプレーン HTML スニペットが生成されます。


この HTML ファイルを使用した後、コンテナーはすべてのオーケストレーションを実行し、アプリをマウントします。この構成では、部分 HTML が前の章で説明したマニフェスト ファイルの役割を果たします。


長所:

  • フレームワークに依存しない: Qiankun は、React、Vue.js、Angular などを含むさまざまなフロントエンド フレームワークをサポートします。


  • 簡素化された統合: Qiankun は、マイクロフロントエンドを作成および管理するための使いやすい API とツールのセットを提供します。


  • スケーラビリティとパフォーマンス: Qiankun は、コードのサンドボックス化、状態の分離、マイクロ フロントエンド間の通信のための効率的なメカニズムを提供します。


短所:

  • 依存関係の競合: 共有依存関係を管理し、マイクロフロントエンド間の互換性を確保するには、慎重な構成と考慮が必要な場合があります。


  • 学習曲線: Qiankun は広範なドキュメントを提供していますが、新しいライブラリを採用するには開発チームの学習曲線が必要になる場合があります。


  • ネットワーク経由で送信される冗長データ: 部分的な HTML スニペットには、ネットワーク経由で送信する必要がある冗長データ (本文、メタ、DOCTYPE タグ) が含まれています。

モジュールフェデレーション

Webpack が提供する機能であるModule Federation は、Web 開発コミュニティで大きな注目を集め、誇大宣伝されています。このテクノロジーにより、開発者は実行時に複数のアプリケーション間でコードを共有できるため、マイクロフロントエンドを構築するための魅力的なオプションになります。


Webpack とのシームレスな統合とランタイムの柔軟性により、モジュール フェデレーションはマイクロ フロントエンドの管理とオーケストレーションに人気の選択肢となっています。


長所:

  • Webpack とのシームレスな統合: すでに Webpack をビルド ツールとして使用している場合は、モジュール フェデレーションを活用すると、セットアップと統合のプロセスが簡素化されます。


  • 実行時の柔軟性: モジュール フェデレーションにより、依存関係の動的な読み込みと共有が可能になり、マイクロ フロントエンドの管理に柔軟性が提供されます。


短所:

  • 限定的なフレームワークのサポート: モジュール フェデレーションは複数のフロントエンド フレームワークと互換性がありますが、特定の使用例では追加の構成や回避策が必要になる場合があります。


  • コミュニティ サポート: Module Federation は比較的新しいテクノロジーで、Webpack 5 のコア プラグインとしてリリースされました (その後v4にバックポートされました)。 Next.js ライブラリも新しく、最近オープンソースとしてリリースされました。すべての新しいツールと同様に、コミュニティが小さくなり、利用できるサポートも少なくなる可能性があります。締め切りが厳しい場合、またはすぐに答えが得られない質問に遭遇することが予想される場合は、この要素を考慮することが重要です。

結論

「マイクロフロントエンド移行の旅」シリーズの第 1 部では、Web モノリスから分散アーキテクチャへの移行の背後にある動機と、そのアイデアを経営陣に売り込むための最初のステップについて説明しました。


私たちは、詳細なパフォーマンス分析を示し、移行のさまざまな段階の概要を説明する技術的なビジョン文書の重要性を検討しました。


次に、マイクロフロントエンドの設計上の考慮事項を詳しく掘り下げ、サーバー側の構成、エッジ側の構成、クライアント側の構成という 3 つのアプローチについて説明しました。


各アプローチには長所と短所があり、選択はグローバル状態の同期、顧客エクスペリエンス、インフラストラクチャの複雑さ、キャッシュなどのさまざまな要因によって決まります。


さらに、single-spa、qiankun、Module Federation などの人気のあるオーケストレーション ライブラリを調査し、その機能、利点、潜在的な課題に焦点を当てました。


シリーズの次のパートでは、マイクロ フロントエンドの移行の旅を続け、その過程でさらに興味深く貴重な洞察を明らかにしていきますので、ぜひご参加ください。


元々は2023 年 4 月 18 日にhttps://thesametech.comで公開されました


Twitter で私をフォローしたり LinkedIn に接続して新しい投稿に関する通知を受け取ることもできます