モジュールフェデレーションについて話す前に、まずフロントエンドモジュールが複数のプロジェクトでどのように再利用されるかを理解しましょう
プロジェクト間のモジュール再利用スキーム
1.npm 包
フロントエンド アプリケーションにはパッケージ管理ツールが不可欠で、モジュールを npm パッケージにアップロードし、必要なプロジェクトにインポートして、いくつかの共通モジュールを再利用できます。
2.monorepo
monorepo
複数のプロジェクト コードを 1 つのウェアハウスに保存するソフトウェア開発モデルです。モノリポジトリ内のすべてのプロジェクトは互いに独立していますが、異なるプロジェクトは相互に参照できます。
3. git submodule
Git はコードを再利用するためのサブモジュールを提供します。Git リポジトリはモジュールを再利用するために他のリポジトリ (サブモジュール) を参照し、git commitid
メイン プロジェクトのサブプロジェクトのバージョンを管理できます。このため、複数人で共同作業を行う場合、サブプロジェクトのバージョンが競合しやすく、そのたびにサブモジュールのリファレンスを手動で更新する必要があるため、サブモジュールのバージョン管理が困難になるという問題が発生します。
4. 复制粘贴
CV メソッドは、 再利用コストが最も低いソリューションである可能性があります GitHub には、ホストしているプロジェクト コードの半分が重複しているという統計があります。コピー アンド ペーストによりコードの再利用をすぐに実現できますが、将来の長期保守には悲惨な結果となり、コード保守のコストはますます高くなるでしょう。
5. (Universal ModuleUMD
UMD
Definition) の略称で、UMD は commonjs と amd の仕様を統合し、グローバル変数のエクスポートをサポートしています。 このスキームにはいくつかの欠陥があります。スキームによってエクスポートされるグローバル変数は競合を引き起こしやすく、複数の UMD モジュールが相互に依存している場合、ロード順序を手動で維持する必要があり、これはあまり簡単ではありません 。UMD
tree shaking
先ほど説明したプロジェクト間モジュール再利用スキームのうち、UMD
他の 4 つのタイプを除く最大の制限は、プロジェクトのアップグレード後に、それに依存するすべてのプロジェクトをアップグレード、コンパイル、起動する必要があることです。 1~2プロジェクトなら問題ないかもしれませんが、数十プロジェクトとなると大変です
再利用モジュールのバージョンをアップグレードして、それに依存するすべてのプロジェクトを個別にデプロイして起動する必要がなくなり、アップグレードされたモジュールをオンライン環境にロードできるようにする解決策はありますか?
webpack5 は、上記の問題を解決するモジュール フェデレーションを提供します。これにより、CDN (リモート モジュール) を使用してプロジェクト間でコードを直接共有できるようになり、npm パッケージをローカルにインストールし、ビルドして公開する必要がなくなりました。
モジュールフェデレーションの概要
公式サイトの紹介文は以下の通りです。
複数の独立したビルドでアプリケーションを形成できます。これらの独立したビルドは互いに依存せず、独立して開発およびデプロイできるため、マイクロ フロントエンドと呼ばれることが多いですが、これに限定されません。
モジュールフェデレーションにはいくつかの重要な概念があります
リモート
モジュールプロバイダーとして、モジュールを外部にエクスポートし、ホストによって参照されるようにします。
ホスト
モジュールのコンシューマとして、Remote によって提供されるモジュールを動的にロードできます。
共有
リモートとホストは同じ依存関係を共有して、パッケージ化の繰り返しを回避し、パッケージ サイズを削減できます。
次の図では、3 つの関係がはっきりとわかります。
使い方
webpack5は ModuleFederationPlugin
モジュールフェデレーションを利用するためのプラグインを提供しています。プラグインの設定項目は以下の通りです
リモート設定
new ModuleFederationPlugin({
name: "component_app",
filename: "remoteEntry.js",
exposes: {
"./Button":"./src/Button.jsx",
},
shared: ["react", "react-dom"]
})
name
モジュール名です。他のモジュールがモジュールを正しく参照できるようにするためにモジュールを識別するために使用されます。
filename
他のプロジェクトがエクスポートされたモジュールをロードする出力モジュールのファイル名を指定するために使用されます。
exposes
エクスポートする必要があるモジュールを指定するために使用されます
shared
共有する必要がある依存モジュールを指定するために使用されます。両方のアプリケーションが同じ依存関係を使用する場合、shared を使用して依存関係を共有し、パッケージ サイズを削減できます。
ホスト構成
new ModuleFederationPlugin({
name: "main_app",
remotes: {
"component-app":"remote_url"
},
shared: ["react", "react-dom"]
})
についてHost
、 remotes
構成に重点を置く
これは、どのアプリケーションがリモート モジュールをロードする必要があるかを指定するために使用されます。その component-app
リモート モジュールのエイリアスと、 リモートremote_url
によって エクスポートされた ファイルのアドレスです。filename
プロジェクトに共有モジュールを導入します (Button
上記の Remoteによって エクスポートされたモジュールを 例として、 Host プロジェクトで使用します)。これは非同期モジュールであるため、 import()
によって参照される必要があります。
React.lazy(() => import('component-app/Button'))
複数のプロジェクトがある場合、各プロジェクトを構成した後、 エクスポートされたモジュール Button をHost
便利に使用できます 。このようにして、Button コンポーネントが変更された場合、 Button が 配置されている アプリケーションをパッケージ化し、最新のButton を 再エクスポートする だけで済みます。 他のプロジェクトでは、参照されている ボタン モジュールは最新のリリース コードであるため、個別にビルドしてリリースする必要はなくなりました。Remote
Remote
アドバンテージ
1. シンプルで柔軟な構成
2. 独立した展開をサポートし、オンラインに移行します
3. 実行時にモジュールをロードし、依存関係を共有してアプリケーション パッケージのサイズを削減します
4. モジュール フェデレーションと比較して externals 以及 dll
、オンデマンド ホット スワップをより適切に実現できます
欠点がある
1. 必ず使用しなければなりません webpack5
2. モジュールフェデレーションはruntime
ランタイムに多くの変更を加えており、ランタイムに行うべきことも大幅に増加し、ページのランタイムパフォーマンスに一定の悪影響を及ぼします。 3.
実行時に共有されるため、リモートモジュールのバージョン管理も考慮する必要があります
参考リンク
コミュニティでは、webpack4 はモジュール フェデレーション (https://github.com/module-federation/webpack-4) をサポートします。
これは、webpack テクノロジー スタックから離脱し、モジュール フェデレーション (https://github.com/tnfe/hel) をサポートします。
- 終わり -
Qi Wu 劇団について
Qi Wu Troupe は 360 グループ最大のフロントエンド チームであり、グループを代表して W3C および ECMA メンバー (TC39) の活動に参加しています。Qi Wu Troupe は人材育成を非常に重視しており、エンジニア、講師、翻訳者、ビジネス インターフェース担当者、チーム リーダー、その他の開発方向性を従業員が選択できるほか、技術スキル、専門スキル、一般スキル、リーダーシップスキルなどのコース。Qi Dance Troupe は、あらゆる種類の優れた才能に注目し、オープンで才能を求める姿勢で Qi Dance Troupe に参加することを歓迎します。