📈

マイクロフロントエンドとは?Next.jsを活用した実用的なアプローチ

2024/11/27に公開

https://vercel.com/blog/how-vercel-adopted-microfrontends
Vercelは単一のNext.jsアプリケーションでウェブサイトとダッシュボードを運営してきましたが、会社が成長するにつれていくつかの問題が発生しました。ビルド時間が増加し、依存関係の管理が複雑になり、小さな変更でも全体のビルドが再実行され、開発ワークフローに影響を与えるようになりました。

これを解決するために、Vercelはアプリケーションの構造を再設計し、垂直的なマイクロフロントエンドを導入しました。

垂直的マイクロフロントエンドとは?

マイクロフロントエンドは、大規模なアプリケーションを独立した小さなユニットに分割する手法で、並行開発を可能にします。主に次の2つの分割方式があります:

  1. 垂直的分割(Vertical Split): 各ページが独立したアプリケーションによって処理される方法。
  2. 水平的分割(Horizontal Split): 複数のアプリケーションが同じページ上で動作する方法。
    Vercelは垂直的分割を選択し、ビルド時間を短縮し、依存関係を簡素化しました。

垂直的分割(Vertical Split)

例: 企業ウェブサイトのセクション分割

ページ 1: マーケティング (marketing)
URL: /marketing
説明: 企業の製品紹介ページ。
処理方法: 独立したアプリケーション(marketing-app)で処理。

ページ 2: ダッシュボード (dashboard)
URL: /dashboard
説明: ログイン済みユーザーがデータを管理するためのダッシュボード。
処理方法: 独立したアプリケーション(dashboard-app)で処理。

Vercelはアプリケーションを「マーケティング」「ドキュメント」「ログインダッシュボード」の3つのセクションに分割しました。それぞれのセクションは、ユーザー間で交差が少なく、独立したUIを持つため、垂直的分割に適していました。

定義

アプリケーションの各ページを独立したアプリケーションとして扱う手法。

適用ケース

  • ユーザーが特定のページ間を頻繁に移動しない場合。
  • 各ページの機能とUIが独立している場合。

メリット

  • 各ページが独立しているため、それぞれのアプリケーションを別々にデプロイし、保守可能。
  • ビルド速度が向上し、依存関係を減らすことが可能。

Next.js Multi-Zones構成例

// next.config.js (メインアプリ)
module.exports = {
  async rewrites() {
    return [
      {
        source: '/marketing/:path*',
        destination: 'https://marketing-app.vercel.app/:path*', // マーケティングアプリへのルーティング
      },
      {
        source: '/dashboard/:path*',
        destination: 'https://dashboard-app.vercel.app/:path*', // ダッシュボードアプリへのルーティング
      },
    ];
  },
};

水平的分割(Horizontal Split)

例: ECサイトのページ

コンポーネント 1: product-list(商品リスト)
ページの一部で商品情報を表示。
独立したマイクロフロントエンドアプリで処理。

コンポーネント 2: cart(カート)
同じページでカート機能を処理。
別のマイクロフロントエンドアプリが担当。

メリット

  • ページ単位で分割しないため、ユーザーが1ページ内で多様な機能にアクセス可能。

デメリット

  • ページの読み込み速度が遅くなる可能性がある。
  • デバッグやデプロイの管理が複雑になる。

Web Componentsを活用した構成例

// product-list-app/index.js
class ProductList extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<div>商品リストをレンダリング</div>`;
  }
}
customElements.define('product-list', ProductList);

// cart-app/index.js
class Cart extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<div>カートをレンダリング</div>`;
  }
}
customElements.define('cart-section', Cart);

比較

特性 垂直的分割 (Vertical Split) 水平的分割 (Horizontal Split)
分割単位 ページ単位 ページ内の機能単位
適した状況 各ページが独立し交差が少ない場合 1ページに複数のチームの機能が必要な場合
実装の複雑さ 比較的簡単 複雑(相互作用の管理が必要)
ビルド速度 速い 遅くなる可能性がある
保守性 ページ単位で管理可能 コンポーネント間の依存関係の管理が必要

結論

  • 垂直的分割は、独立したセクションが明確なプロジェクトに適しています。
  • 水平的分割は、単一のページ内で複数の機能を統合する必要がある場合に適しています。

いつマイクロフロントエンドを導入すべきか?

アプリケーションの規模が大きい、または成長し続けている場合

  • プロジェクトの規模が拡大するにつれ、ビルド時間が長くなる。
  • チーム間での作業衝突が頻発したり、依存関係の管理が複雑になる。
  • 一部の小さな変更がアプリケーション全体に影響を及ぼす。

チームが複数に分かれ、それぞれ異なる機能を開発している場合

  • チームごとに独立した作業が可能になり、生産性が向上する。
  • 各チームが担当エリアのみを管理できるよう分離できる。

保守性と拡張性を向上させたい場合

  • プロジェクトを独立したアプリケーションに分割することで、変更が他のエリアに影響を与えない。
  • 新機能の追加や修正が容易になる。

どう始めるべきか?

現在のアプリケーションの分析

現在運用中のアプリケーション内で、関連性が低いセクション(例: ログイン、マーケティングページ、顧客ダッシュボードなど)を特定します。

アプリケーションの分割

セクションを垂直的に分割できる場合は、独立させます。

例:

marketing-app (マーケティングページ)
dashboard-app (ログイン後のダッシュボード)

技術スタックの整理

  • Next.js を使用している場合、Multi-Zonesを導入して自然なルーティング設定を実現。
  • Monorepo構造を採用して、共有コンポーネントを一元管理。

段階的な移行

  • 既存のアプリケーションから、新しいマイクロフロントエンドにトラフィックを徐々に移行。
  • リスクを最小化しながら、安定的に導入可能。

テストとデプロイ

  • 各独立したアプリケーションを個別にテスト。
  • Vercel を使用して迅速かつ簡単にデプロイ。

マイクロフロントエンドは大規模なアプリケーションやチーム環境に適しているため、小規模なプロジェクトでは必ずしも必要ではありません。ただし、Next.jsのMulti-Zones設定だけで、垂直的なマイクロフロントエンドを簡単に始めることができます。覚えておくと役立つかもしれませんね。

Discussion