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

lnlaulya  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(117)

我有几个微型前端React应用程序。所有应用程序都是技术不可知的。这意味着任何应用程序都可以拥有任何库作为依赖项。他们正在使用webpack模块联邦插件。如果依赖项的版本在其他微前端应用中相同,则将共享依赖项。
Micro-frontends应用程序分为以下几组:主微前端应用程序和子微前端应用程序。主应用程序是其他子应用程序的容器。一次只能运行一个Sub应用。
我们公司有React组件的UI套件。库包括CSS变量,全局选择器(* {/* CSS规则 /})。
子应用程序可以将我们的UI套件作为依赖项。如果UI-Kit的版本不同,其中一个Sub应用程序可能会应用错误的样式。工作流程(如何工作):我在浏览器中打开主应用程序,webpack加载主应用程序第一页的所有资源(JS,CSS,字体)。在我打开Sub app 1的页面之后,webpack加载Sub app 1的资源并将其插入到文档中(CSS样式将插入到文档的头部)。我们的UI-kit有CSS模块,但这还不够,因为类的名称不是从CSS规则的内容创建的。此外,CSS变量可以在其中一个版本中改变。此外,Sub应用可能不使用我们的UI-Kit,但UI-Kit中的所有 * CSS规则将应用于此Sub应用。此外,两个Sub应用程序可以使用不同版本的同一个库,这个库可以使用全局或模块CSS。
我需要为每个微前端应用程序应用完全的CSS隔离。
上一次我尝试应用支持完全CSS隔离的shadow DOM。但是其中一个库(cytoscapejs或其插件)调用document.getElementById方法。它返回null,因为它正在查找的元素已在影子根中。我在调查这个案子。
在此之前,我考虑过在我们的UI工具包的CSS模块类的末尾添加一个版本。但它不会使CSS vars的名称唯一。此外,我想我不能重命名我的微前端应用程序构建的外部库的CSS类。
另外,我知道style-loader可以允许使用“use”和“unuse”方法添加和删除样式标签。我可以用它来防止覆盖两个Sub应用程序的样式。但是mini-css-extract-plugin没有这个功能。
我可以尝试用途:has和:not选择器,但我不想处理许多不同的CSS情况(
选择器,css变量等)。我想这条路走错了。

0x6upsns

0x6upsns1#

checkout PostCss Prefix Wrap plugin在CSS样式前添加一个选择器,有助于防止CSS从一个Microfrontend泄漏到另一个Microfrontend。
为了使用插件,安装它并像这样展开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。

相关问题