如何解决模块联合共享服务
我正在使用Angular 11和Webpack 5进行新项目。我的工作基于使用Angular CLI的Manfred Steyer的Module Federation Plugin Example回购。 我不知道如何在两个应用程序之间从共享的本地Angular库中共享单例服务。。
我会尽力解释我的设置。.非常抱歉这将持续多长时间。
简化的文件结构
root
package.json
projects/
shell/
src/app/
app.module.ts
app.component.ts
webpack.config.ts <-- partial config
mfe1/
src/app/
app.module.ts
app.component.ts
webpack.config.ts <-- partial config
shared/
src/lib/
global.service.ts
package.json <-- package.json for lib
角度
两个app.component.ts文件都是相同的
import {GlobalService} from 'shared';
@Component({
selector: 'app-root',templateUrl: './app.component.html'
})
export class AppComponent {
constructor(shared: SharedService) {}
}
global.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class GlobalService {
constructor() {
console.log('constructed SharedService');
}
}
Webpack
shell / webpack.config.ts
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
output: {
publicPath: "http://localhost:5000/",uniqueName: "shell"
},optimization: {
// Only needed to bypass a temporary bug
runtimeChunk: false
},plugins: [
new ModuleFederationPlugin({
remotes: {
'mfe1': "mfe1@http://localhost:3000/remoteEntry.js"
},shared: ["@angular/core","@angular/common","@angular/router"]
})
],};
mfe1 / webpack.config.ts
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
output: {
publicPath: "http://localhost:3000/",uniqueName: "mfe1"
},plugins: [
new ModuleFederationPlugin({
// For remotes (please adjust)
name: "mfe1",library: {type: "var",name: "mfe1"},filename: "remoteEntry.js",exposes: {
'./Module': './projects/mfe1/src/app/app.module.ts',},};
共享库package.json
{
"name": "shared","version": "0.0.1","main": "src/public-api.ts","peerDependencies": {
"@angular/common": "^11.0.0-next.5","@angular/core": "^11.0.0-next.5"
},"dependencies": {
"tslib": "^2.0.0"
}
}
此配置可以编译并运行,但是mfe1
实例化一个新的GlobalService
。我看到“构造的SharedService”已登录到应用程序加载中,然后在加载远程模块后再次登录。我尝试遵循ScriptedAlchemy的another example,但是我不知道如何使它起作用。它要么编译并运行并创建两个实例,要么无法编译,具体取决于我确定如何弄乱我的配置。
ScriptedAlchemy示例使我似乎需要在shared
文件的webpack.config.ts
库数组中引用共享库。这完全有道理,但我无法正常工作
shell/webpack.config.ts and mfe1/webpack.config.ts
...
shared: ["@angular/core","@angular/router","shared"]
如果以这种方式引用本地库,则不可避免地会在构建过程中出现错误
Error: Module not found: Error: Can't resolve 'shared' in '/Path/to/module-federation-plugin-example/projects/shell/src/app'
我发布的示例已简化。希望不会太过分,但这是link to a repo来显示问题
解决方法
TL; DR
- 确保共享服务的所有模块依赖项也已共享。
- 确保在
webpack.config.ts
中正确配置了共享配置
我将注意到我的项目是使用Angular CLI的NX Monorepo。我目前正在使用Angular 11.0.0-next和Webpack 5,在撰写本文时,它们只能作为ng11的可选组件使用。
如果您在tsconfig中使用路径别名,则习惯于导入“ @ common / my-lib”之类的本地库,但是无法在webpack配置中按别名共享模块。此外,如果您使用的是NX,则从绝对或相对库路径导入时,棉绒会抱怨,因此Webpack所需的内容与nx / tslint所需的内容之间是没有联系的。
在我的项目中,我有一些类似以下的库别名
tsconfig.base.json
...
"paths": {
"@common/facades": [
"libs/common/facades/src/index.ts"
],"@common/data-access": [
"libs/common/data-access/src/index.ts"
]
}
要使其在我的webpack配置中起作用。我们必须使用这些别名,但是要使用import
选项告诉webpack在哪里找到库
apps/shell/webpack.config.js
...
plugins: [
new ModuleFederationPlugin({
remotes: {
'dashboard': 'dashboard@http://localhost:8010/remoteEntry.js','reputation': 'reputation@http://localhost:8020/remoteEntry.js'
},shared: {
"@angular/core": {
"singleton": true
},"@angular/common": {
"singleton": true
},"@angular/router": {
"singleton": true
},"@angular/material/icon": {
"singleton": true
},"@common/data-access": {
"singleton": true,"import": "libs/common/data-access/src/index"
},"@common/facades": {
"singleton": true,"import": "libs/common/facades/src/index"
},"rxjs": {
"singleton": true
},"ramda": {
"singleton": true
}
}
})
]
这解决了Webpack在编译时无法找到模块的问题。
第二个问题是我试图共享依赖于公共数据访问服务的公共外观。我不打算共享数据访问服务,因为它们是无状态的,但是这导致我的MFE实例化了新的单例。这必须是因为共享服务具有“未共享”的依赖性。共享我的数据访问层和外观层导致整个应用程序共享单例。
在这里,依赖的问题是最重要的,因为它很难调试。没有错误或任何东西-事情并没有像您期望的那样工作。您甚至可能没有意识到,一开始您有两个共享服务实例。因此,如果遇到此问题,请查看依赖项,并确保您共享所需的一切。这可能是在应用程序之间保持最小共享状态/依赖性的一种论据。
- 有关@ angular / material / icon共享配置的快速说明。在我的应用程序中,我用每个应用程序需要的图标填充MatIconRegistry。我必须共享@ angular / material / icon才能在每个MFE中共享单例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。