使用 Webpack 5 模块联合服务样式和资产

Serving styles and assets with Webpack 5 module federation

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

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

我想可以编译样式并将其放入联合模块的构建资产中,但是无论是否使用联合,这都会破坏链接。

我还在试验这个,但我觉得问一下会很好。有人遇到过这个问题吗?

好吧,我要 post 我想出的东西,它不是很漂亮,但它似乎适用于 CSS 资产。

首先,我在远程模块的构建中将它们分开: 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();
  }));
}

它不是最理想的,但我想不出更好的东西。

我认为实现这一点的最优雅方法是将微前端的全局 styles.scss 导入它的入口模块 component.scss 并在入口模块 component.ts 中设置 encapsulation: ViewEncapsulation.None 为了打破它的样式封装,这反过来又会导致该样式在全球范围内应用。