Vite插件:通过hash前缀实现CSS作用域隔离,解决模块联邦中的样式冲突
npm install @jiayouzuo/css-scope-viteVite插件:通过hash前缀实现CSS作用域隔离,解决模块联邦中的样式冲突问题。
在模块联邦(微前端)架构中,主应用和远端应用可能使用不同版本的antd,导致样式冲突:
```
主应用(antd 5.x):.ant-btn { color: blue; }
远端应用(antd 4.x):.ant-btn { color: red; }
→ 样式互相覆盖!
使用本插件后:
``
主应用:.ha1b2c3d-ant-btn { color: blue; }
远端应用:.he5f6g7h-ant-btn { color: red; }
→ 完全隔离!
- antd 4.x / 5.x
- @designable/react (低代码设计器)
- @formily/antd (通过 antd 的 ConfigProvider 自动支持)
- 用户自定义的 CSS 类名
`bash`
npm install @jiayouzuo/css-scope-vite -D或
pnpm add @jiayouzuo/css-scope-vite -D
`typescript
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import cssScopePlugin from '@jiayouzuo/css-scope-vite'
export default defineConfig({
plugins: [
// ⚠️ 重要:cssScopePlugin 必须放在 react() 之前!
cssScopePlugin({
scope: '[hash:8]', // hash长度,默认8位
projectId: 'my-app', // 项目标识,用于生成唯一hash
include: [
'src/', // 处理用户代码
'node_modules/antd/', // 处理antd的CSS和JS
'node_modules/@designable/' // 处理@designable的CSS和JS
],
exclude: [] // 排除的目录(可选)
}),
react()
]
})
`
Vite插件按数组顺序执行。本插件需要处理原始的JSX代码来识别和替换className:
` // cssScopePlugin处理后 // 最后由react()编译成 如果react()先执行,JSX会被编译成React.createElement | 选项 | 类型 | 必填 | 默认值 | 说明 | 重要:只有在 include ` 如果只配置了 'src/' 1. CSS处理:使用PostCSS给所有类选择器添加hash前缀 ` / 转换后 / `jsx
// 原始JSX代码
React.createElement("div", { className: "ha1b2c3d-header-box" })
`调用,本插件就无法识别className属性了。配置选项
|------|------|------|--------|------|
| scope | string | 是 | - | hash格式,如 [hash:8] |
| projectId | string | 否 | package.json的name | 项目标识,用于生成唯一hash |
| include | string[] | 是 | - | 需要处理的目录列表 |
| exclude | string[] | 否 | [] | 排除的目录列表 |$3
中配置的路径才会被处理,包括:
- CSS/Less 文件的选择器转换
- JSX/TSX 文件的 className 转换
- antd/@designable 的 prefixCls 修改typescript`
include: [
'src/', // 用户代码
'node_modules/antd/', // antd 的 CSS 和 JS
'node_modules/@designable/' // @designable 的 CSS 和 JS
],则 antd 和 @designable 的样式不会被处理。工作原理
2. JS处理:
- 用户代码:使用Babel替换className字符串
- antd:修改 defaultPrefixCls 变量Layout.defaultProps.prefixCls
- @designable:修改 'h' + md5(projectId).slice(0, hashLength)
3. Hash生成:$3
css
/ 原CSS /
.ant-btn { color: blue; }
.dn-app { background: #fff; }
.header-box { padding: 10px; }
.ha1b2c3d-ant-btn { color: blue; }
.ha1b2c3d-dn-app { background: #fff; }
.ha1b2c3d-header-box { padding: 10px; }
`jsx
/ 原JSX /