フレームワークこのページを編集

マイクロフロントエンド

マイクロフロントエンドは、アプリケーションをより小さく、より管理しやすい単位に分割する方法です。各マイクロフロントエンドは独立したアプリケーションであり、独立して開発、テスト、デプロイすることができます。これにより、開発チームやインフラをより簡単に拡張することができます。

マイクロフロントエンドは、アプリケーション開発をスケールさせる素晴らしい方法です。マイクロフロントエンドを使用することで次のことが可能になります。

注意: この機能は現在実験的に提供されているものです。

lazarv/react-serverでビルドされたアプリはマイクロフロントエンドとして使うことができます。アプリ内のどの場所でもマイクロフロントエンドを使用することができます。ただし、マイクロフロントエンドのルートがアウトレットとして動作するように実装する必要があります。HTMLドキュメントを使用することはできません。HTMLフラグメントをレンダリングするだけです。最も簡単な例として段落をレンダリングしてみます。

export default function MicroFrontend() {
  return (
    <p>
      This is a micro-frontend!
    </p>
  );
}

ホスティングするアプリケーションはhtmlタグ、headタグ、bodyタグを複数レンダリングできないのでマイクロフロントエンドの中ではhtmlタグ、headタグ、bodyタグを含めないようにしてください。

Note: React Server Components、クライアントコンポーネント、サーバ関数は、サーバサイドレンダリングを使用して@lazarv/react-serverフレームワークを使用する場合、マイクロフロントエンドですべてサポートされています。

@lazarv/react-server はアプリケーションにマイクロフロントエンドを実装するためのツールセットを提供しています。RemoteComponent` コンポーネントを使うと、リモートURLからマイクロフロントエンドをロードすることができます。これにより、オンデマンドでマイクロフロントエンドをロードし、サーバーサイドレンダリングを使ってアプリケーションでレンダリングすることができます。

RemoteComponent コンポーネントは src プロパティを受け取り、マイクロフロントエンドのURLを指定します。このコンポーネントを使うことで、それぞれが独立して開発・デプロイされた複数のマイクロフロントエンドからアプリケーションを構成することができます。

import RemoteComponent from "@lazarv/react-server/remote";

export default function Home() {
  return (
    <div>
      <h1>Hosting application</h1>
      <RemoteComponent src="http://localhost:3001" />
    </div>
  );
}

ビルド時に remote フラグを使用して RemoteComponent のソースを static としてエクスポートした場合でも、コンポーネントは正しく動作します。RemoteComponent はマイクロフロントエンドの静的なコンテンツに置き換えられます。静的なマイクロフロントエンドコンテンツをエクスポートする方法については、ドキュメントの 静的生成 セクションを参照してください。

また、ビルド時に RemoteComponent を静的コンテンツとして使用しながら、ホスティングアプリケーションをエクスポートすることもできます。RemoteComponentはマイクロフロントエンドの静的コンテンツに置き換えられます。このように、マイクロフロントエンドアプリケーションとホスティングアプリケーションの両方をビルド時に静的に生成することで、マイクロフロントエンドアーキテクチャで静的コンテンツを使用する場合にも最高のパフォーマンスを実現できます。

マイクロフロントエンドでストリーミングレスポンスを動作させるには、RemoteComponentdefer を prop として渡す必要があります。最初のコンテンツはサーバサイドレンダリング中にレンダリングされ、残りのコンテンツは最初のコンテンツがレンダリングされて RemoteComponent がハイドレートされた後にマイクロフロントエンドからストリーミングされます。

import RemoteComponent from "@lazarv/react-server/remote";

export default function Home() {
  return (
    <div>
      <h1>Hosting application</h1>
      <RemoteComponent src="http://localhost:3001" defer />
    </div>
  );
}

また、ReactServerComponentコンポーネントを urldefer props と共に使用して、リモートURLからマイクロフロントエンドをロードすることも可能です。このコンポーネントは RemoteComponent コンポーネントに似ていますが、クライアント側でマイクロフロントエンドをレンダリングするだけです。これは、Astroサーバーアイランドが server:defer 属性で動作するのとよく似ています。outletsがどのように動作するかについては、クライアントサイドナビゲーションに関するドキュメントのルーターのセクションを参照してください。

import { ReactServerComponent } from "@lazarv/react-server/navigation";

export default function Home() {
  return (
    <div>
      <h1>Hosting application</h1>
      <ReactServerComponent url="http://localhost:3001" defer />
    </div>
  );
}

マイクロフロントエンドを使用する場合、ホスティングアプリケーションとマイクロフロントエンド間で依存関係を共有する必要があります。インポートマップを使用して、ホスティングアプリケーションとマイクロフロントエンド間で共有される依存関係を指定できます。

インポートマップは、インポート指定子とモジュールのURLの対応を指定するJSONファイルです。react-server.config.jsonファイルの importMap オプションを使って、アプリケーションのインポートマップを指定することができます。

{
  "importMap": {
    "imports": {
      // ...
    }
  }
}

各アプリの react-server.config.json ファイルでインポートマップを指定すると、ホスティングアプリケーションとマイクロフロントエンドは指定された依存関係を共有します。

共有依存関係を外部から読み込むには、react-server.config.json ファイルで resolve.shared オプションを使用します。このオプションを使うと、リモートURLから読み込むべき共有依存関係を指定することができます。

{
  "resolve": {
    "shared": [
      "react",
      "react/jsx-dev-runtime",
      "react/jsx-runtime",
      "react-dom",
      "react-dom/client",
      "react-server-dom-webpack/client.browser",
    ]
  }
}

react-server.config.jsonファイルで共有依存関係を指定すると、ホスティングアプリケーションとマイクロフロントエンドは指定したリモートURLから共有依存関係をロードします。

lazarv/react-serverがインポートマップで正しく動作するためには、インポートマップで reactreact-jsx/runtime(または react/jsx-dev-runtime)、react-domreact-dom/clientreact-server-dom-webpack/client.browser のソースを指定する必要があります。

CDNから開発中の依存関係を使用したい場合は、インポートマップでこれらの依存関係のソースを指定できます。しかし、これらの依存関係の開発バージョンが必要であることには注意してください。

注意: ホスティングアプリケーションとマイクロフロントエンドでは、クライアント側とサーバー側の両方で、まったく同じバージョンの reactreact/jsx-dev-runtimereact/jsx-runtimereact-domreact-dom/clientreact-server-dom-webpack/client.browser を使用する必要があります。そうしないと、互換性の問題が発生する可能性があります。

インポートマップを開発環境と本番環境の両方で使用するには、それぞれの環境用の設定ファイルを作成し、インポートマップを指定する必要があります。以下の設定ファイルは、esm.shからReactを使用するインポートマップを使用する方法の例です。

開発では、ホスティング・アプリケーションを使ってクライアント・コンポーネントを提供することができます。

react-server.development.config.json
export default { importMap: { imports: { react: "https://esm.sh/[email protected]?dev", "react/jsx-dev-runtime": "https://esm.sh/[email protected]/jsx-dev-runtime?dev", "react/jsx-runtime": "https://esm.sh/[email protected]/jsx-runtime?dev", "react-dom": "https://esm.sh/[email protected]?dev", "react-dom/client": "https://esm.sh/[email protected]/client?dev", "react-server-dom-webpack/client.browser": "https://esm.sh/[email protected]/client.browser?dev", "http://[::1]:3001/": "/", "http://localhost:3003/": "/", }, }, resolve: { shared: [ "react", "react/jsx-dev-runtime", "react/jsx-runtime", "react-dom", "react-dom/client", "react-server-dom-webpack/client.browser", ], }, };

本番環境では、@lazarv/react-serverモジュールだけをマッピングして、各マイクロフロントエンドと共有します。

react-server.production.config.json
export default { importMap: { imports: { react: "https://esm.sh/[email protected]", "react/jsx-runtime": "https://esm.sh/[email protected]/jsx-runtime", "react-dom": "https://esm.sh/[email protected]", "react-dom/client": "https://esm.sh/[email protected]/client", "react-server-dom-webpack/client.browser": "https://esm.sh/[email protected]/client.browser", "http://localhost:3003/client/__/__/packages/react-server/": "/client/__/__/packages/react-server/", }, }, resolve: { shared: [ "react", "react/jsx-runtime", "react-dom", "react-dom/client", "react-server-dom-webpack/client.browser", ], }, };

上記の設定ファイルの他に、静的なエクスポートを react-server.config.json ファイルで指定します。

react-server.config.json
export default { export() { return [ { path: "/", remote: true, }, ]; }, };

マイクロフロントエンドの例については、@lazarv/react-serverリポジトリのmicro-frontends exampleをチェックしてください。

サンプルを実行するには、@lazarv/react-serverリポジトリをクローンし、ルートディレクトリで以下のコマンドを実行してください。

pnpm install
pnpm --filter ./examples/remote dev