このコンテンツは自動機械翻訳サービスによる翻訳版であり、皆さまの便宜のために提供しています。原本の英語版と異なる誤り、省略、解釈の微妙な違いが含まれる場合があります。ご不明な点がある場合は、英語版原本をご確認ください。
午前6時55分に更新されました。PT
本日は、垂直マイクロフロントエンド(VMFE)用の新しいWorkerテンプレートをご紹介します。このテンプレートを使用すると、複数の独立したCloudflare Workersを単一のドメインにマッピングできます。これにより、チームは完全に独立した環境でマーケティング、ドキュメント、ダッシュボードを個別に提供しながら、ユーザーには単一のシームレスなアプリケーションを提供できます。
ほとんどのマイクロフロントエンドアーキテクチャは「水平」型です。つまり、1つのページの異なる部分が異なるサービスから取得されるということです。垂直マイクロフロントエンドは、URLパスごとにアプリケーションを分割することで、異なるアプローチを採用しています。このモデルでは、「/blog」パスを所有するチームは、コンポーネントだけを所有するだけでなく、フレームワーク、ライブラリ選択、CI/CDなど、そのルートの垂直スタック全体を所有しています。パスのスタック全体、またはパスのセットを所有することで、チームは自分たちの仕事の真の所有権を持ち、自信を持って出荷することができます。
チームは成長に伴い、さまざまなフレームワークが様々なユースケースに対応するという問題に直面します。例えば、マーケティングWebサイトはAstroではより効果的に活用でき、ダッシュボードはReactでより優れたものになるかもしれません。あるいは、多くのチームが集合体としてリリースするモノリシックなコードベースがあるとします。複数のチームによる新しい機能を追加する更新は、単一のチームが後退を導入したために、フラストレーションで元に戻されることがあります。技術的な実装の詳細をユーザーから隠し、チームが完全な自律性とドメインの制御を使用して、統一されたユーザーエクスペリエンスを開発できるようにする方法とは?
その答えは、垂直マイクロフロントエンドです。開発者の問題点をどのように解決するかについて掘り下げてみましょう。
垂直マイクロフロントエンドとは、単一の独立したチームが、ユーザーインターフェースからCI/CDパイプラインまで、アプリケーションの機能全体を所有するアーキテクチャパターンです。これらのスライスはドメイン上のパスによって定義され、個々のWorkersを特定のパスに関連付けることができます。
/ = Marketing
/docs = Documentation
/blog = Blog
/dash = Dashboard
さらに一歩進んで、ダッシュボードなど、より詳細なサブパスWorkerの関連付けに焦点を当てることもできます。ダッシュボード内では、URLパスに深さを追加することで、さまざまな機能や製品をセグメント化できる(例:/dash/product-a)など)と2つの製品間を移動することは、2つのまったく異なるコードベースを意味する可能性があります。
垂直マイクロフロントエンドでは、次のようなことも可能になります。
/dash/product-a = WorkerA
/dash/product-b = WorkerB
上記のパスはそれぞれ独自のフロントエンドプロジェクトであり、共有コードは一切ありません。product-aとproduct-bのルートは、独自のフレームワーク、ライブラリ、CI/CDパイプラインが定義され、独自のチームが所有する別々にデプロイされたフロントエンドアプリケーションにマッピングされます。最後に。
エンドツーエンドで独自のコードを所有できるようになりました。しかし今、私たちはこうした個別のプロジェクトをつなぎ合わせる方法を見つけ、さらには、統一された体験であるかのように感じさせる方法を見つける必要があります。
Cloudflareでも、多くのチームが独自の製品を所有しているため、私たち自身がこの痛点を経験することになります。チームは、自分たちが管理できない変更がユーザー体験に影響を与えるという事実に対処しなければなりません。
現在、社内ではダッシュボードについても同様の戦略を用いています。ユーザーがコアダッシュボードからZero Trust製品に移動すると、実際にはまったく別個の2つのプロジェクトであり、ユーザーはパス/:accountId/oneによってそのプロジェクトにルーティングされるだけです。
これらの個々のプロジェクトをつなぎ合わせ、統合された体験のように感じさせることは、考えるほど難しくありません。CSSのマジックを数行しか必要としないからです。当社が絶対的に避けたいことは、実装の詳細や社内決定をユーザーに漏洩することです。もし、このユーザーエクスペリエンスを1つのまとまりのあるフロントエンドのように感じさせることができなければ、ユーザーに対して重大な不当行為を行ってしまうことになります。
この巧妙な手口を使用するために、ビュー移行とドキュメントのプリロードがどのように機能するかを理解するために、少し移動してみましょう。
エンドユーザーにスムーズに感じてもらいながら、2つの異なるページをシームレスに移動したい場合、ビュートランジションが非常に便利です。次のページが表示されるまで保持する特定のドキュメントオブジェクトモデル要素を定義し、変更の処理方法を定義することで、マルチページアプリケーション用の極めて強力なアルゴリズム発表ツールを実現します。
しかし、さまざまな垂直マイクロフロントエンドを異なると感じさせることは許容以上である場合があるかもしれません。例えば、マーケティングWebサイト、ドキュメント、ダッシュボードが、それぞれ独自に定義されているかもしれません。ユーザーは、これら3つの部分間を移動する際に、これら3つすべてが統一感を持っていると感じることはありません。しかし…ダッシュボード(例:/dash/product-a & /dash/product-b)、ユーザーは決してそれらが2つの異なるリポジトリ/ワーカー/プロジェクトであることを知るべきではありません。
では、話は十分にして、仕事に取り掛かりましょう。2つの別々のプロジェクトをユーザーに1つであるかのように感じさせるのは、手間がかからないことだと述べましたが、もしCSS View Transitionsについてまだ聞いたことがないなら、きっと驚くでしょう。
シングルページアプリ(SPA)とマルチページアプリ(MPA)の異なるビュー間で、あたかも1つのビューであるかのように感じさせることができるとお伝えしたら、どうなるでしょうか?ビュー遷移を追加する前に、2つの異なるWorkersが所有するページ間を移動すると、次のページ全体のレンダリングが開始されるまで、数百ミリ秒間、インタースティシャルの読み込み状態はブラウザの真っ白な画面となります。ページはまとまりのあるものではなく、もちろん単一ページのアプリケーションのようにも感じられません。
各サイト間の複数のナビゲーション要素として表示されます。
真っ白なページではなく、要素を際立たせたい場合は、CSS View Transitionを定義することで実現できます。以下のコードは、現在のドキュメントページに、ビュー遷移イベントが発生しようとしているときに、ナビゲーションドキュメントオブジェクトモデル要素を画面上に表示し続けるよう指示しています。そして、既存ページと宛先ページの間に何らかのデルタが存在する場合は、簡単な移行でアニメーションを作成します。
突然、2つの異なるWorkersが1つのように感じられます。
@supports (view-transition-name: none) {
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0.3s;
animation-timing-function: ease-in-out;
}
nav { view-transition-name: navigation; }
}
3つの異なるサイト間の単一のナビゲーション要素として表示されます。
2つのページ間の推移をシームレスに見せ、クライアントサイドのSPAと同じくらい瞬時に感じられるようにしたいと考えています。現在、FirefoxとSafariはSpeculation Rulesをサポートしていませんが、Chrome/Edge/Operaは、より新しい概念であるSpeculation Rulesをサポートしています。推測ルールAPIは、特にドキュメントURLの将来のナビゲーションのパフォーマンスを向上させるように設計されており、複数ページのアプリケーションを1ページのアプリケーションのように感じさせることができます。
コード例としては、特定フォーマットのスクリプトルールを定義する必要があるのは、サポートするブラウザに、当社のWebアプリケーションに接続されている他のバーティカルスライス(何らかの共有ナビゲーションでリンクされている可能性が高い)をプリフェッチする方法を指示することです。
<script type="speculationrules">
{
"prefetch": [
{
"urls": ["https://product-a.com", "https://product-b.com"],
"requires": ["anonymous-client-ip-when-cross-origin"],
"referrer_policy": "no-referrer"
}
]
}
</script>
そうすることで、アプリケーションは他のマイクロフロントエンドをプリフェッチし、メモリ内キャッシュに保持するため、これらのページに移動する場合は、ほぼ瞬時に移動できるようになります。
明確に識別できる垂直切断(マーケティング、ドキュメント、ダッシュボード)には必要でないかもしれません。ユーザーはそれらの間のわずかな負荷を想定するからです。ただし、特定の可視的エクスペリエンス(例:サインアップページ内など)です。
View TransitionsとSpeculation Rulesの間では、まったく異なるコードリポジトリを結び付けて、1つのページアプリケーションから提供されるように感じることができます。可能性が高いでしょう。
そこで、複数のアプリケーションをホストする仕組みと、リクエストが流れるにつれてそれらをつなぎ合わせる方法が必要になります。1つのCloudflare Workerを「ルーター」として定義することで、(エッジにある)1つの論理ポイントがネットワークリクエストを処理し、そのURLパスを担当するバーティカルマイクロフロントエンドに転送することができます。さらに、1つのドメインをそのルーターWorkerにマッピングできて、残りのルーターは「そのまま」機能します。
Cloudflare Workerのサービスバインディングをまだ体験していない方は、ぜひ一度お試しください。
サービスバインディングによって、公開されているURLを経由することなく、あるWorkerが別のWorkerを呼び出すことができます。サービスバインディングにより、Worker AはWorker B上でメソッドを呼び出すこと、あるいはWorker AからWorkerにリクエストを転送することができます。さらに詳しく説明すると、ルーター Workerは、定義された各垂直マイクロフロントエンドWorkerを呼び出すことができます(例:マーケティング、ドキュメント、ダッシュボードなど)を作成し、それぞれがCloudflare Workersであったと仮定します。
なぜこれが重要なのですか?これはまさに、これらの縦積みを「つなぎ合わせる」メカニズムです。次のセクションでは、リクエストルーティングがどのようにトラフィックのスプリットを処理しているかについて説明します。しかし、これらのマイクロフロントエンドをそれぞれ定義するには、ルーター WorkerのWrangler定義を更新し、どのフロントエンドを呼び出すことができるかを把握する必要があります。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "router",
"main": "./src/router.js",
"services": [
{
"binding": "HOME",
"service": "worker_marketing"
},
{
"binding": "DOCS",
"service": "worker_docs"
},
{
"binding": "DASH",
"service": "worker_dash"
},
]
}
上記のサンプル定義は、ルーター Workerで定義されており、3つの追加のWorkers(マーケティング、ドキュメント、ダッシュボード)へのリクエストを許可することを示しています。許可許可は非常に簡単ですが、リクエストのルーティングとネットワークレスポンスのHTML書き換えに関する、より複雑なロジックをご紹介します。
必要に応じて呼び出すことができる他のさまざまなWorkersについての知識があると、今度はネットワークリクエストをどこに転送するかを知るためのロジックを整備する必要があります。Router Workerはバニティドメインに割り当てられるので、受信リクエストは全てネットワークエッジに最初に到達します。そして、リクエストを処理するWorkerを決定し、その結果であるレスポンスを管理します。
最初のステップは、URLパスを関連するWorkersにマッピングすることです。特定のリクエストURLを受け取った場合、どこに転送する必要があるかを知る必要があります。これはルールを定義することによって行われます。ワイルドカードルート、動的パス、パラメーター制約をサポートしていますが、基本的な部分(リテラルパスプレフィックス)に焦点を当てながら、その点をより明確に説明します。
この例では、3つのマイクロフロントエンドがあります。
/ = Marketing
/docs = Documentation
/dash = Dashboard
上記の各パスは、実際のWorkerにマッピングする必要があります(上記のセクションのサービスに関するWrangler定義を参照)。ルーター Workerでは、次のデータで追加の変数を定義し、どのパスがどのサービスバインディングにマッピングされるべきかを知ることができます。これで、リクエストが来たときにユーザーをどこにルーティングすればよいのかがわかるようになりました。ROUTESという名前でWrangler変数を定義し、以下の内容を記述します。
{
"routes":[
{"binding": "HOME", "path": "/"},
{"binding": "DOCS", "path": "/docs"},
{"binding": "DASH", "path": "/dash"}
]
}
Webサイトパス/docs/installationを訪問するユーザーを想像してみましょう。内部では、リクエストは最初にルーター Workerに到達し、WorkerはどのURLパスがどの個々のWorkersにマッピングされるかを理解します。/docsパスプレフィックスがDOCSサービスバインディングにマッピングされ、Wranglerファイルを参照することでworker_docsプロジェクトを示しています。Cloudflareのルーター Workerは、/docsが垂直マイクロフロントエンドルートとして定義されていることを認識しているため、パスから/docsプレフィックスを削除し、リクエストをworker_docs Workerに転送してリクエストを処理し、最終的に、得られたレスポンスを返します。
ところが、なぜ/docsパスをドロップするのでしょうか?これは、ルーター Worker経由でWorkerにアクセスしたときに、ルーター Workerの外部から呼び出されたかのようにリクエストを処理するために、URLをクリーンアップするために行われた、詳細な実装の選択です。他のCloudflare Workerと同様に、worker_docsサービスには、アクセスできる独自のURLがある場合があります。当社は、そのサービスURLを独立して動作させたいと考えました。新しいRouter Workerに接続されている場合、自動的にプレフィックスの削除が処理されるため、サービスは独自に定義されたURLから、またはRouter Workerを通じてアクセスすることができます。どちらの場所も問題ありません。
URLパス(例:/docs または /dash)を使用することで、リクエストを簡単に転送することができますが、当社のレスポンスに、パスコンポーネントを介してリバースプロキシされているとは知らないHTMLが含まれている場合、問題が発生します。
例えば、当社のドキュメントWebサイトのレスポンスに、<img src="./logo.png" />のような画像タグがあるとします。ユーザーがhttps://website.com/docs/でこのページを訪問している場合、logo.pngファイルの読み込みは失敗する可能性が高くなります。これは、/docsパスがルーターWorkerによってのみ人工的に定義されているためです。
ルーター Worker経由でサービスにアクセスする時だけ、返されるブラウザレスポンスが有効なアセットを参照するように、絶対パスのHTML書き換えを行う必要があります。実際には、リクエストがルーター Workerを通過すると、そのリクエストは正しいService Bindingに渡され、そこからレスポンスを受け取ります。クライアントに返す前に、ドキュメントオブジェクトモデルを書き換える機会があるため、絶対パスが表示される場合は、プロキシされたパスでプリペンドします。以前は、HTMLが<img src="./logo.png" />で画像タグを返していましたが、今ではクライアントブラウザに戻る前に修正して、<img src="./docs/logo.png" />にしています。
CSSのビュー移行とドキュメントのプリロードのマジックに少し戻りましょう。もちろん、そのコードを手動でプロジェクトに配置して動作させることもできますが、このルーターWorkerは、HTMLRewriterを使用することで、そのロジックを自動的に処理してくれます。
ルーターワーカーのROUTES変数で、ルートレベルでsmoothTransitionsをtrueに設定すると、CSSトランジションビューのコードが自動的に追加されます。さらに、ルート内でpreloadキーをtrueに設定すると、そのルートのスクリプトコード投機ルールも自動的に追加されます。
以下は、両方の動作例です。
{
"smoothTransitions":true,
"routes":[
{"binding": "APP1", "path": "/app1", "preload": true},
{"binding": "APP2", "path": "/app2", "preload": true}
]
}
今すぐ垂直マイクロフロントエンドテンプレートで構築を始めましょう。
Cloudflareダッシュボードのこちらからディープリンクにアクセスするか、「Workers & Pages」に移動して「アプリケーションを作成」ボタンをクリックしてください。そこから、「テンプレートの選択」、「マイクロフロントエンドの作成」をクリックすると、セットアップの設定を開始できます。
既存のWorkersをマッピングしてView Transitionを有効にする方法については、ドキュメントをご確認ください。お客様がどのような複雑なマルチチームアプリケーションをエッジで構築されるのか、楽しみにしています。