两次使用同一个库时隔离微前端中的 CSS
P粉321676640
P粉321676640 2024-01-01 09:43:23
0
1
495

我有几个微前端反应应用程序。 所有应用程序均与技术无关。这意味着任何应用程序都可以有任何库作为依赖项。 他们正在使用 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粉321676640
P粉321676640

全部回复(1)
P粉904405941

签出 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。
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板