既存の大規模な実世界のアプリに Webpack-5 モジュール フェデレーションを実装しようとしています。angular-plugin-architecture-with-module-federation のようなプラグインのデモを試みています。上記のリンクされたサンプル アプリケーションでアプリとプラグイン間の通信をシミュレートするために、SharedService を shared-library に追加しました。インスタンスは 1 つしかなく、この例ではすべてが問題なく動作します。
ただし、既存のアプリでは、サービスのインスタンスが 2 つあるため、これは機能しません。最初のインスタンスはアプリで作成され、プラグインが読み込まれると 2 番目のインスタンスが作成されます。コンストラクターでコンソールに書き込むことでこれを確認すると、2行あります。さらに、これはソースにブレークポイントを追加することで確認できます。プラグインがロードされた後、ブラウザの開発者ツール -> ソースに shared.service.ts の 2 つのソース ファイルがあります。
アプリは、上記のスクリーン キャプチャの最初のソース ファイルを使用します。プラグインは dist のファイルを使用します。両方がライブラリの同じインスタンスを使用するため、同じサービスを使用するように構成する方法は? 以下に、さらに詳しい情報を示します。
プロジェクト/プラグイン/webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
output: {
publicPath: 'http://localhost:4201/',
uniqueName: 'plugins'
},
optimization: {
// fix a temporary bug
runtimeChunk: false
},
plugins: [
new ModuleFederationPlugin({
name: 'plugins',
library: { type: 'var', name: 'plugins' },
filename: 'remoteEntry.js',
exposes: {
'./Plugin1': './projects/plugins/src/app/plugin1/plugin1.component.ts',
'./PropertyPlugin': './projects/plugins/src/app/property-plugin/property-plugin.component.ts',
'./Plugin2': './projects/plugins/src/app/plugin2/plugin2.component.ts'
},
shared: {
'@angular/core': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/common': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/forms': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/router': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
rxjs: {
singleton: true,
eager: true,
requiredVersion: "6.5.5",
},
shared: {
singleton: true,
eager: true,
requiredVersion: '0.0.1',
import: 'dist/shared'
}
}
})
]
};
src/webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
output: {
publicPath: 'http://localhost:4200/',
uniqueName: 'app'
},
optimization: {
// fix a temporary bug
runtimeChunk: false
},
plugins: [
new ModuleFederationPlugin({
shared: {
'@angular/core': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/common': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/forms': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
'@angular/router': {
singleton: true,
eager: true,
requiredVersion: '11.0.0',
},
rxjs: {
singleton: true,
eager: true,
requiredVersion: "6.5.5",
},
shared: {
singleton: true,
eager: true,
requiredVersion: '0.0.1',
import: 'dist/shared'
}
}
})
]
};
ワークスペースは、ワークスペースの例のようになります。
- projects
- shared
- src
- lib
...
- package.json
...
- plugins
- src
- app
... plugin app is here
- webpack.config.js
- src
- app
... the main app is here
-webpack.config.js
-angular.json
-package.json
別の問題のため、package.json を projects/plugins にコピーする必要があったことを除いて。私はこれに完全に行き詰まっており、成功せずに機能させるためにあらゆることを試みています。