8

我已经在我的 Angular 11 应用程序中成功实现了相对较新的 webpack 5 模块联合系统,因此它可以从另一个构建中按需远程加载模块。

我没有发现的一件事是如何处理样式表和图像等资产。例如,联邦模块中有一个菜单元素需要自己的样式:

  • 将它们放在组件的样式表中会使块膨胀,编译器会抱怨这一点,而且在显示菜单之前它们不会加载
  • 如果样式位于联合模块的全局样式表上,则根本不会加载它们,因为我请求的是子模块而不是主模块(我想)
  • 样式是联邦模块特有的,所以不能放在加载器应用程序中

我想可以编译样式并将其放入联合模块的构建资产中,但是在使用和不使用联合时会破坏链接。

我仍在尝试这个,但我认为问一下会很好。有人有这个问题吗?

4

2 回答 2

3

我认为实现这一目标的最优雅的方法是将微前端的全局 styles.scss 导入它的入口模块 component.scss 和你的入口模块 component.ts 集中encapsulation: ViewEncapsulation.None,以打破它的样式封装,这将在引领该样式在全球范围内应用。

于 2022-01-02T00:49:59.710 回答
0

好吧,我将发布我想出的东西,它并不漂亮,但它似乎适用于 CSS 资产。

首先,我在远程模块的 build: angular.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();
  }));
}

这是次优的,但我想不出更好的办法。

于 2021-09-18T06:54:34.717 回答