フロントエンド分解
概要
GitLab フロントエンドは、同時にビルドされる複数の Webpack バンドルとして構築・出荷されています。このトラックでは、UI モジュールを独立して開発、ビルド、テスト、デプロイできるようにフロントエンドをモジュール化し、共有シェルアプリケーションと明示的なモジュール契約を通じて統合します。これはバックエンドのバウンデッドコンテキストに対応するフロントエンド側の対応物です。
このドキュメントは、全体的な分解の取り組みにおける動機、エージェント型への必然性、目標を共有しています。
動機
GitLab フロントエンドには、より速い開発イテレーションとより良いユーザー体験を妨げる一連の課題があります。
問題
- Rails への密結合。 GitLab はマルチページアプリケーションであり、Rails がルーティング、ページ構成、テンプレートレンダリングツリーを所有しています。スタンドアロンのフロントエンドをテスト対象にできないため、統合テストと E2E テストは完全な Rails アプリケーションに対して実行する必要があります。さらに、約 440 個のファイルが Vue アプリを hydrate するために
el.datasetを読み取り、77 個のファイルがwindow.gonを読み取っています。フィーチャーフラグは API 代替なしに、すべてwindow.gon.features経由で注入されています。この結合によりフィードバックループが遅くなり、すべてのフロントエンド変更をフルスタックパイプラインで検証しなければなりません。 - フロントエンドがバックエンドのパフォーマンス問題を覆い隠している。 現在の Rails アプリは遅く(初期 HTML に 400-500ms)、フロントエンドアーキテクチャはこの制約に対処するのではなく、その制約を前提に設計されています。ページは、クライアントアプリが読み込まれる前にユーザーが「何か」を見られるように部分的なコンテンツをサーバー側でレンダリングするか、完全にクライアント側でレンダリングするかのどちらかです。どちらの場合も、高コストなデータ取得がフロントエンドに押し出され、すでに遅いサーバーレスポンスの上にレイテンシが追加されます。副次的なページ要素もこれを悪化させます。サイドバーと Duo Chat は認証済みのすべてのページに出荷され、そのレンダリングコストにより、主要コンテンツをどれほど最適化してもパフォーマンス上限が生まれます。たとえば Rapid Diffs が消費するページレンダリング時間は約 30% にすぎず、残りは副次的な要素です。300ms で読み込まれるべきページが数秒かかっています。
- CSS アーキテクチャがない。 223 ファイルにまたがる 36,000 行の SCSS には、分離、コロケーション、所有権がありません。適切な CSS の書き方に関するガイドラインもありません。スタイルは影響する HTML から遠く離れた場所にあり、カスケードに強く依存しています。影響範囲が不明なため、任意の SCSS ファイルを変更すると、すべての統合テストを実行する必要があります。Tailwind はレガシー CSS の上に載せられており、複雑さとメンテナンスを増やしています。
- アーキテクチャレイヤーがない。 フロントエンドコードは構造上の規約がないまま
app/assets/javascripts/全体に散らばっています。どこからでも何でも import できます。spec はテスト対象のファイルとは別の場所にあり、スタイルはテンプレートとは別の場所にあります。プラクティスやパターンは共有されず、新しいアプリごとに、作者がたまたま見た既存アプリを基に独自の構造を発明しています。コードは自己複製します。良いパターンと同じくらい簡単に悪いパターンも広がります。これはエージェント型開発にも悪影響を及ぼします。エージェントは一貫しないアプローチを平均化し、どのパターンが特定の問題に合うかを判断できないからです。 - CI のコストと時間。 フロントエンドの予測的テスト選択は存在しますが、ほとんど効果的ではありません。ほとんどのフロントエンド MR は完全な E2E スイートの実行にフォールバックします。RSpec system spec にはフロントエンド変更に対するカバレッジベースのマッピングがなく、静的なファイルパターンマッチングだけです。Fixture 生成(8 並列 RSpec ジョブ)は、予測的選択を完全に無視します。
- アプリ間の調整。 アプリ間通信は、3 つの場当たり的なパターン(mitt ベースの EventHubs、DOM CustomEvents、Pinia/Apollo Client cache/Vue reactive variables を通じた状態共有)に依存しており、正式な契約はありません。
- 外部サービス向けのバンドルサイズリスク。 Module federation やランタイムでのモジュール共有は存在しません。各外部サービス(frontend island など)は Vue、GitLab UI、Apollo の重複コピーを出荷することになり、モノリス内でそのようなサービスの追加を許可しないようにするべきです。
目標
- 明示的な契約。 2 つのコード片の関係がツールによって追跡できない場合、テスト、ビルド、ロードの目的では存在しません。これは JS、CSS、Rails からのデータ、アプリ間通信に適用されます。
- データプロバイダー向けの明確なガイダンス。 初期サーバーデータは、クリティカルレンダリングパスのため、またリクエストのウォーターフォールを避けるためにのみ使用し、それ以外の場合は API の呼び出しを優先します。
- CSS の所有権。 グローバル CSS は最小限にするべきです。CSS は影響する HTML に対してスコープが限定され、同じ場所に置かれなければならず、ページエントリーポイントのビルドグラフの一部になります。
- 高速で信頼できる CI。 - フロントエンドのみの変更では、可能なリグレッションを検証するために、できるだけ小さいテストサブセットを実行するべきです。
ワークストリーム(WIP)
1. ビルドパイプラインをモダナイズする
TODO: 独立したフロントエンドモジュールのデプロイを可能にします。ターゲットとなるビルドトポロジー、モジュール単位のビルド、デプロイモデルを説明します。
2. Webpack 4 → Webpack 5 / Vite へ移行し、Vue 3 を完了する
TODO: Webpack 4 から Webpack 5 / Vite への移行パスと、それによって可能になる Vue 3 移行を、順序付けとリスクを含めて整理します。
3. モジュール契約を定義する
TODO: モジュールが境界をまたいで認可、ユーザーコンテキスト、フィーチャーフラグをどのように管理するかを定義します。これは、パッケージのパブリックインターフェイスに相当するフロントエンド版です。
4. 支援インフラストラクチャを構築する
TODO: シェルアプリケーション、モジュールレジストリ、Context provider API、およびモジュールがそれらへ登録し、それらを通じて統合する方法を指定します。
5. Frontend LabKit
TODO: 共有ライブラリとツールを標準化し、モジュール間で一貫したユーザー体験を確保します。
プルーフオブコンセプト
関連するフロントエンド PoC は、すでに モジュラーモノリス: PoC に記録されています:
参考資料
最終更新 July 30, 2026: Merge pull request #483 from kyama0/translation/batch-2026-07-29-1 (
c955a93f)