两次使用同一个库时在微前端中隔离 css

问题描述 投票:0回答:1

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

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

我们公司有带有react组件的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 隔离的影子 DOM。但是其中一个库(cytoscapejs 或其插件)调用了 document.getElementById 方法。它返回 null,因为它正在寻找的元素已经在影子根中。我正在调查这个案子。

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

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

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

css shadow-dom css-modules micro-frontend webpack-module-federation
1个回答
0
投票

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

为了使用插件安装它并像这样扩展你的 webpack.config:

npm i postcss-prefixwrap

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。
© www.soinside.com 2019 - 2024. All rights reserved.