我已经在我的 Angular 11 应用程序中成功实现了相对较新的 webpack 5 模块联合系统,因此它可以从另一个版本按需远程加载模块。
我一无所知的是如何处理样式表和图像等资源。例如,联合模块中有一个菜单元素需要自己的样式:
我认为样式可以被编译并放入联合模块的构建资产中,但是当它在有联合和没有联合的情况下使用时,这会破坏链接。
我仍在尝试这个,但我认为最好问一下。有人遇到这个问题吗
我认为实现这一点的最优雅的方法是将微前端的全局 styles.scss 导入到它的入口模块 component.scss 中,并在入口模块 component.ts 中设置
encapsulation: ViewEncapsulation.None
以打破它的样式封装,这反过来又会导致该样式在全球范围内应用。
好吧,我将发布我的想法,它并不漂亮,但它似乎对于 CSS 资源来说工作得很好。
首先,我在远程模块的构建中将它们分开: 角度.json:
"styles": [
"projects/xxx-admin/src/styles/styles.scss",
"projects/xxx-admin/src/styles/admin.scss",
{
"input": "projects/xxx-admin/src/styles/admin.scss",
"bundleName": "admin_module_styles",
"inject": false
}
],
这会生成一个具有清晰的非自动生成名称的 CSS。然后我们从应用程序的路由中加载联合模块:
{
path: "admin",
component: AdminPanelComponent,
canActivate: [XxxAdminGuard],
loadChildren: () => {
const baseUrl = getAdminFrontendBaseUrl();
return loadAdminStyles().then(
() => loadRemoteModule({
remoteName: "xxx_admin",
remoteEntry: `${baseUrl}/remoteEntry.js`,
exposedModule: "AdminModule",
}).then((m) => m.AdminModule));
},
},
...
export function loadAdminStyles(): Promise<void> {
return new Promise((resolve => {
const baseUrl = getAdminFrontendBaseUrl();
const el = document.getElementById("admin-module-styles");
// Load one instance, do it like this to handle errors and retrying
if (el) {
el.remove();
}
const headEl = document.getElementsByTagName("head")[0];
const styleLinkEl = document.createElement("link");
styleLinkEl.rel = "stylesheet";
styleLinkEl.id = "admin-module-styles";
styleLinkEl.href = `${baseUrl}/admin_module_styles.css`;
headEl.appendChild(styleLinkEl);
resolve();
}));
}
这不是最理想的,但我想不出更好的办法了。
在microfront中,将资产转移到assets/mfe_name。通过 microfront 的名称,您可以从父主机进行代理。
主持人:
"/assets/*mfe_name*/*": {
"target": "*mfe_host*",
"secure": true,
"changeOrigin": true
},
启动:ngserve --proxyConfig=proxy
因此,您可以从本地主机和产品上获取文件,以便从远程主机访问
所以你可以做如下:
在远程应用程序中将
assets
文件夹重命名为某个唯一的名称,例如remote-app1
全局样式必须移至 shell 应用程序或使用
encapsulation emulated
创建容器组件。不封装不是一个好方法,因为它不仅会为 shell 应用全局样式,还会影响其他应用程序。 (使用 :host ::ng-deep 在此容器中深入设计)
在 shell 应用程序中,创建一个服务工作线程来侦听所有获取请求。一旦获取请求到来,检查其路径前缀并将 URL 更改为适当的远程 URL(检查 png、svg、.json 后缀以了解粒度)。
就像在 sw
self.addEventListener('fetch', (event) => {...}
为什么喜欢这个?
如果您还想使用翻译(ngx-translate),请在容器组件(point2)中使用
TranslateModule.forChild
和 isolate: true
。