直接import或link全局CSS必然污染,因CSS天生全局生效;须禁用全局引入,改用动态注入容器、配置构建路径、源头改UI框架类名前缀(如ep-button)并隔离CSS变量与字体动画。

微前端子应用里直接 import 或 <link rel="stylesheet"> 全局 CSS,99% 会污染主应用或其他子应用——这不是配置没开对,是浏览器根本不管“微前端”这回事,CSS 就是全局生效的。
为什么 import 'xxx.css' 在子应用里是高危操作
qiankun 不拦截 ES 模块导入的 CSS,Vite/Webpack 构建时把 import 'element-plus/dist/index.css' 编译成 <style></style> 标签并插入 document.head,沙箱完全不感知。结果就是:两个子应用都 import 了同一份 normalize.css,DOM 里出现两份 identical 的 <style></style>,加载顺序决定谁赢,视觉表现伪随机。
- 子应用 JS 中执行
document.head.innerHTML += '<style>...</style>'—— 绕过所有劫持 -
@import嵌套在已加载的 CSS 文件内,qiankun 不解析内容,直接放行 - CSS-in-JS 库(如
styled-components)调用insertRule或操作document.styleSheets,不走 DOM 插入流程 - 主应用已注入
el-input__inner边框规则,子应用再加载一份同名规则,后者的border: none直接覆盖前者
必须禁用子应用全局 CSS 导入,改用三步法控制注入
目标不是“让样式进得去”,而是“让它只在该在的地方起作用”。关键在切断全局路径、限定作用域、源头改类名。
- 移除所有
import 'xxx.css'和<link href="/css/xxx.css">,尤其是 UI 框架和重置类库 - 用 JS 动态加载 CSS 并注入到子应用容器内:
container.appendChild(styleEl),确保样式只影响该容器后代 - Vite 子应用配
build.base = window.__POWERED_BY_QIANKUN__ ? '/subapp-order/' : '/';Webpack 配publicPath动态值,避免构建产物中 CSS 路径为/css/app.abc.css(404)而非/subapp-order/css/app.abc.css
UI 框架类名必须从源头改写,不能靠容器前缀兜底
给容器加 class="subapp-order" 再写 .subapp-order .el-button 是无效的——因为主应用和其他子应用也用 el- 前缀,权重相同,后加载者胜出。唯一解是让子应用的 el-button 变成 ep-button。
立即学习“前端免费学习笔记(深入)”;
- 在
main.ts初始化时传参:app.use(ElementPlus, { namespace: 'ep' }) - 新建
src/styles/element/index.scss,内容为:@forward 'element-plus/theme-chalk/src/mixins/config.scss' with ($namespace: 'ep'); - Vite 用户:在
vite.config.js的css.preprocessorOptions.scss.additionalData中注入该 SCSS 文件路径;Webpack 用户:在sass-loader的additionalData里做同样配置 - 构建后检查产物 HTML/CSS,确认所有类名是
ep-button而非el-button;否则说明 SCSS 变量未生效
CSS 变量、字体、动画这些“隐形全局项”最容易被忽略
--color-primary 这种变量不走选择器权重,而是在继承链上就近生效。子应用在 body 上设 style="--color-primary: red",主应用所有用该变量的组件瞬间变色,DevTools 里只显示最终值,查不到源头。
- CSS 变量必须强制加 app-id 前缀:
--mf-order-header-bg,禁止--header-bg -
@font-face、@keyframes、:focus-visible行为默认全局注册,无法加前缀,需主应用统一提供,子应用禁用重复引入 - 子应用容器上加
all: initial可切断继承链,但会重置font-family等基础属性,必须手动补全


















