独立站のマイクロフロントエンド:複数チームの協働、技術スタックの分離、デプロイの独立性
1. マイクロフロントエンドは結局何を解決するのか
マイクロフロントエンドは、1つのフロントエンドアプリを業務領域ごとに複数の子アプリに分割し、各子アプリを独立したチームが開発、独立してデプロイし、最後に「シェルアプリ」(Shell)がそれらを同じページに組み立てます。バックエンドのマイクロサービスと同じ発想です。バックエンドが大きなシステムを複数のサービスに分割して独立デプロイするように、フロントエンドでも同じことができます。
解決する具体的な課題は3つあります。1つ目は、複数チームが同じコードベースを編集し、マージコンフリクトが増え続けること。2つ目は、AチームがReact 19に上げたいのにBチームはまだReact 17を使っており、上げるかどうかで互いに足を引っ張ること。3つ目は、小さな変更でも全量ビルドしてサイト全体をリリースし、リグレッションテストがサイト全体に及ぶため、リスクがどんどん大きくなること。この3つはいずれも「組織の規模」から生じるもので、技術力の不足ではありません。
直感に反する判断ですが、マイクロフロントエンドのメリットはチーム規模に比例します。チームが小さいほど、マイクロフロントエンドのマイナス効果は大きくなります。3人のフロントエンドチームがマイクロフロントエンドに分割すると、シェルアプリ、ルーティング調整、アプリ間通信という3つの余分な複雑さを自分たちで抱え込むことになり、そもそもマージコンフリクトなど起きていません。WordPressの技術スタックの選び方は、こちらをご覧くださいWordPress技術スタックの選定。
| 指標 | マイクロフロントエンドに不向き | マイクロフロントエンドを検討可 | マイクロフロントエンド必須 |
|---|---|---|---|
| フロントエンドチーム数 | 1つ | 2つ | 3つ以上 |
| コードベースの行数 | 10万行未満 | 10万〜50万行 | 50万行以上 |
| リリース頻度の差 | 毎週1回で統一 | 一部チームが月1回更新 | 週次と日次の混在 |
| 技術スタックの衝突 | 完全に統一 | 多少の衝突あり | 複数フレームワークが併存 |
| プロダクト形態 | マーケティングサイトのみ | マーケティングサイト+簡単な管理画面 | マーケティングサイト+複雑なSaaS+管理画面 |
| デプロイの複雑さ | 単一リポジトリ・単一ビルド | 単一リポジトリ・複数ビルド | 複数リポジトリ・複数ビルド |
2. よくある3つの実装方式と、その選び方
1つ目はModule Federationです。webpack 5に標準搭載された機能で、子アプリはビルド時に公開するモジュールを宣言し、親アプリが実行時に読み込みます。統合度が高いのが利点ですが、webpackのバージョンを揃える必要があり、デバッグも複雑になりがちです。すでにwebpackを使っているReact/Next.jsチームに向いています。
2つ目はimport-map + SystemJSです。実行時にJSONファイルで子アプリのURLを宣言し、親アプリが必要に応じて読み込みます。技術スタックを完全に分離できるのが利点で、子アプリはReact、Vue、Svelteから自由に選べます。欠点は、アプリ間のスタイル分離とルーティングの調整を自分で実装する必要があることです。
3つ目はモノレポで複数アプリを管理する方法です。NxやTurborepoで複数のサブパッケージを管理し、それぞれを独立してビルド・デプロイします。コード共有がしやすいのが利点ですが、リポジトリが大きくなるほどビルドが遅くなり、大規模チームには向きません。内部リンクの仕組みの作り方は、次をご覧ください内部リンク体系。
| プラン | 技術スタックの分離度 | 学習コスト | ビルドの複雑さ | 向いている規模 |
|---|---|---|---|---|
| モジュールフェデレーション(Webpack 5) | 中(親フレームワークを統一) | 2〜3週間 | 中 | Reactチーム、20〜50人 |
| import-map + SystemJS | 高(フレームワークを混在可能) | 3〜4週間 | 高 | 複数フレームワークの併用、50人以上 |
| Monorepo + 複数アプリ | 低(依存関係を共有) | 1〜2週間 | 低 | 同一フレームワークの複数チーム、10〜30人 |
| iframeマイクロフロントエンド | 極めて高い | 極めて低い | 低 | サードパーティページを一時的に統合 |
三、B2B独立サイトにマイクロフロントエンドが本当に必要なのはどんなときか
純粋なマーケティング型のB2B独立サイト、つまりトップページ、製品ページ、ブログ、会社概要、お問い合わせしかないサイトにマイクロフロントエンドは不要です。こうしたサイトのコード量は通常5万行以内で、1人でも無理なく保守できます。マイクロフロントエンドに分割するのは、わざわざ面倒を増やすだけです。
本当に必要なのは、マーケティングサイト、顧客ポータル、代理店管理画面の3つを兼ね備えたサイトです。たとえば海外向けの産業プラットフォームでは、公式サイトのコンテンツをマーケティングチームが担当し(Next.js、SEO優先)、顧客の注文・照会システムをプロダクトチームが担当し(React、インタラクション優先)、代理店管理画面を運用チームが担当します(Vue、ツール優先)。3チームのリリースサイクルは異なり、技術スタックも異なり、コード量はいずれも10万行以上です。こうした場合、マイクロフロントエンドは3つの子アプリを同じドメイン下の異なるルートに組み合わせ、各チームが独立してデプロイでき、互いに影響しません。サイト監視を複数アプリにどう対応させるかは、次をご覧くださいサイト監視とアラート。
具体例:海外向けSaaS企業が、公式サイトをNext.js、ユーザーダッシュボードをReact+Reduxで構築し、2つのアプリを別々のサブドメインにデプロイしていました。しかし、ユーザーがログイン後に公式サイトからダッシュボードへ移動する際にクロスドメインとなり、体験が途切れることが分かりました。Module Federationで2つのアプリを1つの親アプリに統合し、ナビゲーションバーを統一し、ログイン状態を共有しつつ、それぞれ独立してデプロイできるようにしました。公式サイトの変更はダッシュボードに影響せず、ダッシュボードの変更は公式サイトに影響しません。リリース頻度は週1回から1日2回になりました。
| 課題 | モノリシックアプリのやり方 | マイクロフロントエンドのやり方 | メリット |
|---|---|---|---|
| リリース頻度 | 全量リグレッション、週1回 | サブアプリを個別にデプロイ、1日に何度も | リリース速度が5〜10倍に |
| 技術スタックのアップグレード | 全リポジトリ一括だとリスク大 | サブアプリごとに順次アップグレード | アップグレード周期が四半期から週単位に |
| チーム連携 | 同じリポジトリでマージ衝突が頻発 | リポジトリを分けてインターフェースを取り決め | マージ衝突が80%減少 |
| 障害の影響範囲 | 1つのバグでサイト全体が停止 | サブアプリのクラッシュは局所にとどまる | 障害の爆発半径を縮小 |
| 新メンバーの立ち上がり | サイト全体を理解する必要がある | 自分のサブアプリだけ見ればいい | 立ち上がり期間が4週間から1週間に |
4. マイクロフロントエンドで最もハマりやすい3つの落とし穴
1つ目の落とし穴はスタイルの相互汚染です。2つのサブアプリがどちらもBootstrapを使っていて、同じページに読み込むとスタイルが崩れます。解決策はCSSの名前空間(各サブアプリにプレフィックスを付ける)かShadow DOMによる分離です。技術的な難題ではありませんが、プロジェクト初期に規約を決めておかないと、後からの修正が苦痛になります。
2つ目の落とし穴はアプリ間の通信です。ユーザーがマーケティングサイトでフォームに入力し、そのデータをユーザーセンターのダッシュボードに持っていきたいとします。2つのサブアプリが完全に独立していると、通信はURLパラメータかlocalStorageに頼ることになり、データが増えると破綻します。解決策はシェルアプリにグローバルな状態管理(zustandなど)を置き、サブアプリは取り決めたインターフェース経由で読み書きする方法です。サブアプリ同士を直接呼び出してはいけません。
3つ目の落とし穴はパフォーマンスの断片化です。各サブアプリがそれぞれReactを読み込むと、ユーザーはページ表示時にReactを3つ分ダウンロードすることになり、JSの総量が500KBから1.2MBに膨らみます。解決策はReactやVueといった共通依存をシェルアプリに置き、サブアプリは共有スコープ経由で参照して重複してバンドルしないようにする方法です。サードパーティスクリプトの管理方法はこちらをご覧くださいサードパーティスクリプトの管理。
| 落とし穴 | 症状 | 解決策 | 予防措置 |
|---|---|---|---|
| スタイル汚染 | AサブアプリのボタンがBサブアプリのスタイルになる | CSSプレフィックスまたはShadow DOM | プロジェクト初期にスタイル規約を策定 |
| 状態共有の混乱 | サブアプリ間でデータが消える | シェルアプリで状態管理を一元化 | 共有インターフェースとデータ構造を取り決め |
| JSサイズの重複 | 各サブアプリがフレームワークを個別にバンドル | 共通依存をシェルアプリに引き上げ | ビルド時に重複バンドルを分析 |
| ルートの非同期 | サブアプリがリロード後に404 | シェルアプリでルートを一元管理 | ルートルールを集中管理 |
| デバッグが困難 | エラーがどのサブアプリ由来か分からない | エラー監視を統一しサブアプリを識別 | Sentryにサブアプリのタグを付与 |
FAQ よくある質問
マイクロフロントエンドとiframeの違いは?iframeを直接使えばダメなの?
5人のフロントエンドチームでコードベースが8万行、マイクロフロントエンドに分割すべき?
マイクロフロントエンドは初回表示速度を遅くしますか?
WordPressサイトでマイクロフロントエンドはできますか?
マイクロフロントエンドのデプロイフローはどう組む?
マイクロフロントエンドはSEOに影響しますか?
最後に
マイクロフロントエンドは「規模が駆動する」アーキテクチャ判断です。チームが小さいうちは負担になり、大きくなれば特効薬になります。分割すべきかどうかは、技術トレンドではなく、いま実際に抱えている痛点で判断してください。毎週マージコンフリクトの対応に追われていませんか? 文言をひとつ変えるだけでも全量リグレッションが必要ですか? 技術スタックの不一致で2つのチームが互いに足を引っ張り合っていませんか? 3つのうち2つが「はい」なら、分割を検討する段階です。
導入は、いちばん痛い1点から分割を始めるのがおすすめです。まずリリース頻度が最も高いサブアプリ(通常はマーケティングキャンペーンページ)を独立させ、ほかの部分はしばらくそのままにします。3か月走らせて効果を確認してください。独立リリースでデプロイ速度が実際に上がり、マージコンフリクトも確かに減ったなら、2つ目を分割します。最初からサイト全体を5つや6つのサブアプリに分割するのは、自分で穴を掘るようなものです。
覚えておきたい一言。マイクロフロントエンドは「分割できない大チーム」のためのメスであり、「まだ育っていない小さなサイト」のための飾りではありません。チームがその規模に達していなければ、分割は単純な問題を複雑にするだけです。
