搜索

首页  >  问答  >  正文

两次使用同一个库时隔离微前端中的 CSS

我有几个微前端反应应用程序。 所有应用程序均与技术无关。这意味着任何应用程序都可以有任何库作为依赖项。 他们正在使用 webpack 模块联合插件。如果其他微前端应用程序的版本相同,则依赖项将被共享。

微前端应用程序分为几组:主微前端应用程序和子微前端应用程序。 主应用程序是其他子应用程序的容器。一次只能运行一个子应用程序。

我们公司有带有反应组件的 UI-Kit。库包括 CSS 变量、全局选择器 (* {/* CSS 规则 */})。

子应用程序可以将我们的 UI-Kit 作为依赖项。如果 UI-Kit 的版本不同,子应用程序之一可能会应用错误的样式。 工作流程(工作原理):我在浏览器中打开主应用程序,webpack 加载主应用程序第一页的所有资源(JS、CSS、字体)。之后,我使用 Sub app 1 打开页面,webpack 加载 Sub app 1 的资源并将其插入到文档中(CSS 样式将插入到文档的头部)。 我们的 UI-kit 有 CSS 模块,但这还不够,因为类的名称不是根据 CSS 规则的内容创建的。此外,CSS 变量可能会在其中一个版本中发生更改。此外,子应用程序可能不会使用我们的 UI-Kit,但 UI-Kit 中的所有 * CSS 规则都将应用于该子应用程序。此外,两个子应用程序可以使用不同版本的同一库,并且该库可以使用全局或模块CSS。

我需要为每个微前端应用程序应用完整的 CSS 隔离。

上次我尝试应用支持完全CSS隔离的shadow DOM。但库之一(cytoscapejs 或其插件)调用 document.getElementById 方法。它返回 null,因为它正在查找的元素已在影子根中。我正在调查此案。

在此之前,我考虑过在 UI-Kit 的 CSS 模块类末尾添加一个版本。但它不会使 CSS 变量的名称变得唯一。 此外,我认为我无法从我的微前端应用程序构建中重命名外部库的 CSS 类。

此外,我知道样式加载器可以允许使用“use”和“unuse”方法添加和删除样式标签。我可以用它来防止覆盖两个子应用程序的样式。但mini-css-extract-plugin没有这个功能。

我可以尝试使用 :has 和 :not 选择器,但我不想处理许多不同的 CSS 情况(* 选择器、css 变量等)。我认为这是一个错误的方法。

P粉321676640P粉321676640350 天前516

全部回复(1)我来回复

  • P粉904405941

    P粉9044059412024-01-02 00:35:28

    签出 PostCss Prefix Wrap 插件,它将选择器添加到 CSS 前面样式有助于防止 CSS 从一个微前端泄漏到另一个微前端。

    为了使用该插件,请安装它并扩展您的 webpack.config,如下所示:

    const PrefixWrap = require('postcss-prefixwrap')
    ...
    ...
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: true,
        postcssOptions: {
          plugins: [
            PrefixWrap('#mfe_id_<appname>', {
              nested: '&',
            })],
        },
      },
    }

    请遵守 #mfe_id_ 命名并将相同的 ID 添加到 MFE 中最顶部的元素。

    优点

    • 易于实现,并且也适用于嵌套 CSS 规则。
    • 无需担心根(即 html、body)元素的前缀问题 由 prefixRootTags 参数负责。默认情况下,该选项是 设置为 false,表示根元素不会加前缀, 但将替换为提供的#mfe_id_。

    缺点

    • 需要使用 PostCSS。

    回复
    0
  • 取消回复