@jiayouzuo/vite-plugin-css-scope
v0.1.4
Published
Vite 插件:CSS 作用域隔离,解决微前端和模块联邦中的样式冲突问题
Maintainers
Readme
@jiayouzuo/vite-plugin-css-scope
Vite 插件:CSS 作用域隔离,解决微前端和模块联邦中的样式冲突问题。
功能特性
- CSS 选择器包裹:
.btn→[data-scope-appProcess="1"] .btn - JSX 自动注入:自动给模块联邦暴露的组件父元素添加作用域属性
- HTML 自动注入:自动给
<body>添加作用域属性 - Portal 容器处理:自动处理 antd Modal、Drawer、Dropdown、Select、Tooltip、Message、Notification 等全局挂载组件
- 智能过滤:自动跳过
:root、html、body、@keyframes等全局选择器 - HOC 支持:支持
forwardRef、memo等高阶组件 - 多格式支持:CSS、Less、SCSS、Sass、JSX、TSX
安装
npm install @jiayouzuo/vite-plugin-css-scope -D
# 或
pnpm add @jiayouzuo/vite-plugin-css-scope -D使用方法
// vite.config.ts
import { defineConfig } from 'vite';
import cssScopePlugin from '@jiayouzuo/vite-plugin-css-scope';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
// ⚠️ 重要:cssScopePlugin 必须放在 react 插件之前
cssScopePlugin({
scope: 'appProcess', // 作用域名称
include: ['src/', 'node_modules/@designable/'], // 要处理的目录
exclude: ['node_modules/antd'] // 排除的目录(可选)
}),
react()
]
});配置选项
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| scope | string | 是 | 作用域名称,会生成 data-scope-{scope}="1" 属性选择器 |
| include | string[] | 是 | 要处理的目录列表(相对于项目根目录) |
| exclude | string[] | 否 | 排除的目录或文件 |
效果示例
CSS 选择器包裹
/* 原代码 */
.btn { color: red; }
.card, .panel { padding: 10px; }
/* 转换后 */
[data-scope-appProcess="1"] .btn { color: red; }
[data-scope-appProcess="1"] .card, [data-scope-appProcess="1"] .panel { padding: 10px; }JSX 组件自动注入(模块联邦)
配合模块联邦使用时,暴露的组件会自动注入作用域逻辑:
// 原代码
function FormDesigner() {
return <div>表单设计器</div>;
}
// 自动转换后
function FormDesigner() {
const __scopeRefCallback = (__el) => {
if (__el) {
const __parent = __el.parentElement;
if (__parent && !__parent.hasAttribute("data-scope-appProcess")) {
__parent.setAttribute("data-scope-appProcess", "1");
}
}
};
return (
<>
<div ref={__scopeRefCallback} style={{width: 0, height: 0, overflow: 'hidden'}} />
<div>表单设计器</div>
</>
);
}HTML 自动注入
<!-- 原代码 -->
<body>
<!-- 转换后 -->
<body data-scope-appProcess="1">Portal 容器自动处理
antd 的 Modal、Drawer、Dropdown、Select、Tooltip、Message、Notification 等组件会将弹层挂载到 document.body,插件会自动处理这些 Portal 容器:
@rc-component/portal- Modal、Drawerrc-trigger- Dropdown、Select、Tooltip、Popover 等rc-notification- Message、Notification
自动跳过的选择器
/* 这些选择器保持原样,不会被包裹 */
:root { --color: red; }
html { font-size: 16px; }
body { margin: 0; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }适用场景
- 模块联邦样式隔离:主应用(antd 5.x)和远端应用(antd 4.x)样式冲突
- 微前端样式隔离:多个子应用样式互不干扰
- 第三方组件库隔离:如 @designable 等组件库的样式隔离
工作原理
- CSS 处理:使用 PostCSS 遍历所有规则,给选择器外层包裹
[data-scope-xxx="1"]属性选择器 - JSX 处理:使用 Babel AST 解析,注入回调 ref,通过辅助 div 获取父元素并添加作用域属性
- HTML 注入:通过 Vite 的
transformIndexHtml钩子给<body>自动加上作用域属性 - Portal 处理:拦截 antd rc-* 组件的容器创建代码,自动注入作用域属性
License
MIT
