微前端父子应用css命名冲突的解决方案

151 阅读1分钟

遇到的问题

微前端项目集成子应用过程中,往往会遇到css命名冲突,样式污染问题。

例如qiankun框架支持沙箱css,可以开启strictStyleIsolation等解决方案。

也可以在项目开发时约定各自的前缀,vue style scoped 样式作用域等避免样式污染。

但很多项目的UI库用的是element-pluselement-ui,大版本都不一致,就必须做样式隔离。

这里采用PostCSS的 postcss-namespace 插件,简单实现添加前缀的方式,支持webpackvite构建,方法都一样。

效果示例

// 转换前
h1, .h1 {
  font-weight: bold;
}
@media screen and (max-width: 500px) {
    h1 {
      font-size: 24px;
    }
}

// 转换后
.global-css h1, .global-css .h1 {
  font-weight: bold;
}
@media screen and (max-width: 500px) {
    .global-css h1 {
      font-size: 24px;
    }
}

实现步骤

1. npm安装依赖包

npm i -D postcss-loader postcss-selector-namespace 

2. 在项目根目录放置一个文件:postcss.config.js

文件内容如下:

module.exports = {
  plugins: {
    'postcss-selector-namespace': {
      namespace(css) {
        // 不需要添加命名空间的文件
        if (css.includes('unNamespace')) return '';
        return '.global-css'
      }
    }
  }
}

3. 在index.html文件,html下增加一个class

<html lang="zh-CN" class="global-css">
    ...
</html>

常见问题

1. html 样式丢失

因为html的样式被转成 .global-css html 了。添加一个不需要添加前缀的文件 unNamespace.less,全局引入。

然后在 postcss.config.js 文件添加一个判断,如果css名包含 unNamespace 字眼,就跳过。

if (css.includes('unNamespace')) return '';

2. postcss-loader 安装失败,提示版本冲突

使用命令:npm i postcss-loader --legacy-peer-deps ,目的是绕过peerDependency, 忽略项目中引入的各个modules之间的相同modules但不同版本的问题并继续安装。