遇到的问题

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

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

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

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

2022-09-03-22-01-27

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

效果示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 转换前
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;
}
}

实现步骤

npm安装依赖包

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

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

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
plugins: {
'postcss-selector-namespace': {
namespace(css) {
// 不需要添加命名空间的文件
if (css.includes('unNamespace')) return '';
return '.global-css'
}
}
}
}

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

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

常见问题

  1. html 样式丢失

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

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

1
if (css.includes('unNamespace')) return '';
  1. postcss-loader 安装失败,提示版本冲突
    使用命令:npm i postcss-loader --legacy-peer-deps ,目的是绕过peerDependency, 忽略项目中引入的各个modules之间的相同modules但不同版本的问题并继续安装。