paint-brush
モノリスを打破する: コード分割テクニックの総合ガイド@aleksandrguzenko
8,160 測定値
8,160 測定値

モノリスを打破する: コード分割テクニックの総合ガイド

Aleksandr Guzenko11m2023/04/24
Read on Terminal Reader

長すぎる; 読むには

マイクロ フロントエンド (MF) を使用して、大規模なプロジェクトの開発チームを編成できます。 MF は、大規模なプロジェクトで開発の複雑さを管理する方法に関する **組織的な決定** に近いものです。 MF はフロントエンドの高速化には役立ちません。逆に、一部の実装では速度が低下することさえあります。
featured image - モノリスを打破する: コード分割テクニックの総合ガイド
Aleksandr Guzenko HackerNoon profile picture


ここ数年、フロントエンド コミュニティでは「マイクロ フロントエンド」(以下、MF) という用語が活発に議論され、使用されてきました。さまざまな企業が、このような アーキテクチャソリューションを構成するアプローチを共有していますが、これまでのところ、MF が Web 上で解決するように設計されている問題、その適用性の基準、および使用上の制限についてはほとんど説明されていません。


この記事では、MF を編成するさまざまな方法を比較し、どのアプローチをどこで使用するかについての推奨事項を作成しようとしました。


この記事は、プロジェクトのアーキテクチャを設計し、プロセスをレイアウトする際にアナリストと開発チームの両方に役立つ可能性があります。また、MF の導入により開発がより管理しやすくなるため、製品所有者にとっても役立ちます。

マイクロフロント アプローチ: それは何で、なぜ必要なのか?

MF の定義に進む前に、プロジェクトで発生する可能性のあるいくつかの問題を見てみましょう。


  1. 大きなプロジェクトがあります。プロジェクトのサイズは通常主観的であり、機能の量と開発者の数によって経験的に決定できます。 1〜2人のフロントエンダーを困惑させるのに十分な仕事があり、同時に彼らが「ひじを押す」ことはない場合-これは小さなプロジェクトであり、3〜6人は中程度であり、6〜8人以上はすでに大きなプロジェクトです.


  2. あなたは大きなチームを持っています。繰り返しになりますが、経験的に、これは 10 人を超えるフロントエンダーであり、残りの参加者はカウントされません。原則として、この規模のチームは、サポートのために特定の機能を担い、独自のアナリスト、バックエンダー、および QA を獲得するサブチームにすでに分割されている可能性があります。


  3. あなたは素晴らしい機能を持っています。 1 人の開発者が管理できるのは、サブチームのコードの一部だけです。コードの残りの部分を改良すると、サブジェクト領域を知らなかったり、サードパーティ ロジックの実装が複雑であったりするため、コストがかかる可能性があります。


問題はさらに悪化する可能性があります。

  • スタックを変更したいという欲求。

  • 関連プロジェクトのファミリをサポートするための会社の要件。


どうすれば多くの人々の間の関係を整理できますか?この規模のプロジェクトでプロセスを構築するにはどうすればよいでしょうか?責任の範囲をどのように適切に描写できますか?収集した問題が多ければ多いほど、マイクロ正面アプローチの導入を検討する価値があります。これは、コードとプロジェクトチームの分解に向けた開発の進化傾向の自然な継続であるため.





したがって、MF アプローチは、モノリシック フロントを、別々のサブチームがアクセスできる別々のリポジトリに格納された別々のコードベースに分割することです。同時に、彼らは独自のデモ スタンド、テスト、およびリリース サイクルを持つことができます/持つべきです。したがって、マイクロフロントはインターフェースの取り外し可能な部分です。ページごとに分割する必要はありません。機能はエンドツーエンドにすることができます (たとえば、企業の ui-kit)。


これとは別に、MF は、大規模なプロジェクトで開発の複雑さを管理する方法に関する組織的な決定であることを強調する価値があります。 MF はフロントエンドの高速化には役立ちません。逆に、一部の実装では速度が低下します。しかし、このアプローチは、責任領域の割り当てと分離されたテストにより、開発自体をスピードアップします。





マイクロフロントエンドと遅延読み込み

逆に言えば、MF と比較して遅延読み込みについて言及する価値があります。それらはさまざまな問題を解決しますが、どちらの場合もアプリケーションを「分割」しているため、すべてが 1 つのことだと考える人もいます。


遅延読み込みは、パフォーマンスの問題を解決します。ユーザーにフロントエンド バンドル全体の読み込みを強制しない方法、必要以上に長く待たせない方法、およびクライアントでフロントをより速く起動し、それとの対話をより早く開始する方法です。


MF はパフォーマンスの問題を解決せず、場合によっては悪化させることさえあります。しかし、これらは特定のサブチームにとってより快適な方法で開発を整理するのに役立ち、上記の問題を最小限に抑えます。

ビルド時間とランタイム

次に、MF を 1 つのアプリケーションに結合するアプローチについて説明します。何を選択しても、ユーザーには単一のアプリケーションのように見える必要があります。アセンブリ段階でも、ユーザー側でのコード実行中にも動的にマージできます。


したがって、MF を編成するすべての方法は、ビルド時間またはランタイムに起因する可能性があります。それぞれに長所と短所があります。


ビルドタイム

ランタイム

型チェック

+

-

バージョニング

+

も意味ない

独立した展開

-

+


型チェックは、最新の開発において重要な役割を果たします。別々の独立したサブチームによって運営される場合、それは必要になります。 MF の一貫性を確保する方法、データを正確に使用して正しい形式で渡す方法など。


ビルド時にマイクロフロントをマージすることで、型をチェックする機会を奪われることはありません。ランタイム ユニオンの場合、本番環境でフロントが突然「爆発」しないように、統合テストを作成する必要があります。


バージョニングと独立した展開は非常に矛盾しています。


  • バージョニングとは、他のチームの MF の任意のバージョンを使用できることを意味します。これは、MF-a の依存関係を他のものからアップグレードするために追加の作業を実行する必要がある場合に特に当てはまります。各チームは、アップグレードに適した時期を選択します。


  • 独立した展開により、チームの自律性と独立性が高まります。常に最新バージョンの MF を使用することが重要です。これには下位互換性が必要です。


バージョニングはランタイム マージでも実装できますが、これは実用的ではありません。独立した展開のためだけにランタイムに接続することは理にかなっており、後者はバージョン管理と一緒に存在することはできません。


次に、MF を結合するための各アプローチの具体的な実装例を見ていきます。

マイクロフロントエンドを整理するアプローチ

iframe

MF を編成する最も古い方法。 iframe は、メイン サイトに表示されるリソースのアドレスを渡すための特別なタグです。結果は、サイト内のサイトです。




利点のうち、実装の容易さ、ロジックとスタイルの完全な分離、独立した展開を行う機能、およびフレームワークへのバインドの欠如に注目する価値があります。


これらの利点は、iframe を挿入するたびにリソースの負荷がかかるため、パフォーマンスが犠牲になります。これを回避することはできません: DOM ノードをデバッグして再接続しようとすると、以前にロードされたリソースが保存されないため、それらを再ダウンロードする必要があります。キャッシュを構成することで、パフォーマンスの低下を最小限に抑えることができます。


これを行うには、不変リソースの時間ベースのキャッシュ無効化を構成する必要があります。幸いなことに、収集された js および css ファイル用のすべての最新の cli は、名前に小さなハッシュを添付します。この方法の欠点には、検索ロボットが後続のインデックス作成のために iframe をレンダリングできないことが含まれます。


長所

短所

簡単な実装

パフォーマンス

ロジックとスタイルの分離

SEO

独立した展開


フレームワークに依存しない



Web コンポーネント

フロントエンドコミュニティは、ネイティブ コンポーネントの作成を長い間待ち望んでいましたが、最終的には、多くの人が期待した大衆的な人気を得ることはありませんでした。最も人気のある 3 つのフロントエンド フレームワーク (React、Vue、Angular) は、今でも独自の方法でコンポーネントを作成しています。


Web コンポーネントで MF を作成する機能があるにもかかわらず、私はこれを実際に見たことがありません。そして、これは偶然ではなく、多くのブロッカーがあります。


  • libs Lit または Stencil のいずれかが十分に普及しておらず、十分に一般的ではありません。さらに、市場には、彼らと協力する方法を知っている、または学ぶ準備ができている専門家が十分にいません。


  • Angular 要素または vue-custom-element はエキゾチックなままです。ネイティブ環境では、それらを使用してもあまり意味がありません。すでにアプリケーションを分割している場合は、通常の npm パッケージに分割して、後で必要に応じてコンポーネントを接続できるようにします。 Web コンポーネントを他のフレームワークで使用するのは合理的ではありません。生成されたコンポーネントとともに、コンポーネントが作成されたフレームワークのミニ バージョンを接続する必要があるからです。


  • 機能の複雑な部分を Web コンポーネントに移動するには、コストがかかる場合があります。コンポーネントとアプリケーションの残りの部分との通信を構成する必要があるため、別のカスタム コンポーネントでページ全体を取り出すことは正当化されない場合があります。


  • 検索ロボットは Web コンポーネントを作成できず、これは SEO の最適化に影響します。

長所

短所

横断的な機能に適しています

実装が難しい

あらゆるフレームワークに対応

SEO

ロジックとスタイルの分離



NPM

npm パッケージを使用した開発には多くの利点があります。開発者は、必要なコンポーネントとファイルをライブラリからインポートするだけです。同時に、タイピングはプロジェクトに保持され、バージョン管理があります。ビルドは最適です。ツリー シェイキングが機能し (ビルド中に未使用のコードが削除されます)、開発者は遅延読み込みを簡単に設定できます。



ただし、この方法には欠点もあります。この場合、MF のバージョンとその推移的な依存関係を維持するだけでなく、スタックの統一性を維持する必要があります。一方、これはプラスになる可能性があります。パッケージの新しいバージョンを公開することにより、他のチームは、追加機能を導入する必要がある場合、または逆に、何かを削除します。


長所

短所

パフォーマンス

独立した展開はありません

SEO

シングルスタック

型チェック


バージョニング



git サブモジュール (または Lerna のようなモノレポを作成する別の方法)

npm パッケージの MF の代わりに、git サブモジュールを検討してください。実際、これらはリポジトリ内のリポジトリであり、その中にリポジトリが存在する場合もあります。サブモジュールに異なるブランチを設定できます。たとえば、機能モジュールには、何も入っていないダミー ブランチを含めることができます。これは、アセンブリを高速化し、他のモジュールが副作用を引き起こさないようにするために必要です。ダミー ブランチは、ローカルでの開発とテストに非常に便利です。







長所と短所という点では、このアプローチは npm パッケージに非常に近いものです。また、パッケージからではなく、隣接するフォルダーから何かをインポートして使用します。


2 つの方法の違いを見てみましょう。


  • 実際、NPM パッケージは、独自のリリースとバージョン管理を備えた有限で適度に分離されたマイクロ製品です。再利用可能な機能を作成することにすべてが集中しています。しかし、アプリケーションは複雑で入り組んでおり、悪臭を放つ可能性があるため、大規模なモノリスをパッケージ化するには非常にコストがかかる可能性があります.これは、追加の準備なしでフォルダーを別のリポジトリに移動するときに、リポジトリを非常に大まかに切り取ることができるため、サブモジュールを検討するのが合理的です。


  • NPM パッケージは再帰的にネストできます。サブモジュールも同様ですが、アセンブリ レベルでは、サブモジュールの 1 つが別のサブモジュールとして異なるフォルダーに複数回含まれている場合、機能の複製を開始できます。この場合、よりフラットなモジュール構造を使用する価値があります。


  • 一度にすべてのパッケージで機能を迅速にロールアウトする必要がある場合、クロスパッケージ開発は非常に不便です。サブモジュールではすべてが同じままですが、他のサブモジュールに影響を与える編集を行うことができます。この場合、デバッグは簡単です。しかし、最終的には、変更自体をマージすることはありません。マージ リクエスト レベルでは、あなたが触れたモジュールを所有するサードパーティ チームが、コードを彼らのルールに合わせることを要求する場合があります。


npm

git サブモジュール

再利用性

機能の荒削り

任意にネストされた依存関係

フラット構造

クロスプラットフォーム開発

モジュール数を問わない開発


シングルスパ

single-spa は基本的に、他のフレームワークを組み合わせたフレームワークです。膨大な数のニュアンスを隠す信じられないほど強力なテクノロジーは、別の記事のトピックです。

スキームは iframe に似ていますが、MF の読み込みは、ネイティブ インポート + インポートマップ、またはポリフィルが必要な場合は Systemjs を介して行われるようになりました。





MF を編成するすべての方法とは異なり、これはさまざまなフレームワークをそれ自体の下に組み合わせるために高度に調整されています。しかし、テクノロジー自体のためにテクノロジーを使用することには注意が必要です。スタック 1 つで十分な場合は、それを使用する必要があります。開発は、技術的に複雑なプロジェクトを維持し、さまざまなアプリケーションの副作用によるバグを修正するという永遠の負担になる可能性があります。ユーザーは不快に感じるかもしれません。クライアントにダウンロードするコードの量が増加します (さまざまな機能のためのさまざまなフレームワークのコア + シングル スパ自体とそのプラグインのコア)。

長所

短所

独立した展開

まだすべてのケースをカバーしていない大規模なドキュメント

フレームワークに依存しない

SEOの難しさ

強力な CLI



Webpack 5 モジュールフェデレーション

MF を作成するために特別に開発された webpack 5 プラグイン。有望な技術: より正確なバンドルと実行時の動的インポートのための小さなビルド プラグイン。


スキームはほぼ 1 対 1 でシングル スパを繰り返しますが、現在はダイナミック インポートを使用して MF をロードします。



長所

短所

独立した展開

低レベル

簡単実現


SSR対応




あなたのケースで何を使用するかを選択する方法は?

何を何に適用できるかを見てみましょう。


  • iframe - 不調和の組み合わせのための単一の挿入

  • Web コンポーネント- 企業の UI キットのように、フレームワークに縛られずにエンド ツー エンドの小さな機能が必要な場合

  • npm パッケージ- プロジェクト間の再利用性がある場合、および/またはビルド時に型チェックが必要な場合

  • git サブモジュール- プロジェクトを大まかに切り刻み、責任範囲を分散する必要がある場合

  • single-spa - 複数のフレームワークを無期限に組み合わせる必要性が強い場合、できれば SSR なしで

  • module-federation - MF を使用するその他のすべてのシナリオ。スタックの統一性を条件とします。


それぞれのアプローチには独自の方法があり、すべてに適切な場所が必要です。 MF に切り替える前に、本当に必要かどうかを検討することをお勧めします。どちらのアプローチを選択しても、開発、CI/CD、またはパフォーマンスのレベルで何かが複雑になることは避けられません。単一のスタックとモノリシック アプリケーションにとどまる機会がある場合は、この機会を喜んで受け入れてください。


もちろん、ユーザーのことも忘れないでください。最終的に、それらは接続されたすべてのフレームワークをダウンロードし、さまざまな機能に MF を不適切に統合することによって発生する可能性のあるバグに耐えます。その結果、企業は、これらすべての実装とサポートにお金を払わなければならなくなります。