@dpdfe/swc-component-marker
v0.0.2
Published
SWC plugin to add component-based class names to React components
Readme
SWC Plugin Component Marker
一个高性能的 SWC 插件,用于自动为 React 组件添加基于组件名称的 CSS 类名,方便组件追踪、调试和样式管理。
✨ 功能特性
- ✅ 全面的组件支持: 支持函数组件、箭头函数组件、类组件和成员表达式组件
- ✅ 智能根元素识别: 只对每个组件的根元素添加类名,避免污染子元素
- ✅ 深度跟踪算法: 智能跟踪 JSX 元素嵌套深度,确保精确的根元素识别
- ✅ Fragment 智能处理: 正确处理 React.Fragment,跳过不渲染 DOM 的元素
- ✅ 第三方库过滤: 自动排除第三方库组件,只处理本地定义的组件
- ✅ 自定义前缀配置: 支持自定义类名前缀,满足不同项目需求
- ✅ 现有类名保护: 智能追加类名,不会覆盖现有的 className 属性
- ✅ 原生元素忽略: 自动忽略原生 HTML 元素(div、span 等)
- ✅ 高性能: 基于 Rust 和 WASM,编译时处理,零运行时开销
🚀 快速开始
安装
npm install @dpdfe/swc-component-marker基本配置
在你的 SWC 配置中添加插件:
{
"jsc": {
"experimental": {
"plugins": [
["@dpdfe/swc-component-marker", {}]
]
}
}
}Rsbuild 配置示例
// rsbuild.config.js
export default {
tools: {
swc: {
jsc: {
experimental: {
plugins: [
["@dpdfe/swc-component-marker", {
"prefix": "component-",
"enabled": true
}]
]
}
}
}
}
};⚙️ 配置选项
{
"jsc": {
"experimental": {
"plugins": [
["@dpdfe/swc-component-marker", {
"prefix": "component-",
"enabled": true,
"excludeLibraries": ["react", "antd", "@mui", "react-router"]
}]
]
}
}
}配置参数说明
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| prefix | string | "component-" | 类名前缀,用于生成组件类名 |
| enabled | boolean | true | 是否启用插件功能 |
| excludeLibraries | string[] | ["react", "antd", "@mui"] | 要排除的第三方库列表 |
📝 转换示例
输入代码
import React from "react";
import { Button } from "antd"; // 第三方库,会被排除
// 函数组件
function MyButton() {
return <button>点击我</button>;
}
// 箭头函数组件
const ArrowComponent = () => <div>箭头函数组件</div>;
// 类组件
class ClassComponent extends React.Component {
render() {
return <div className="existing-class">类组件</div>;
}
}
// 成员表达式组件
const UI = {
Button: () => <button>UI 按钮</button>,
};
function App() {
return (
<div>
<MyButton />
<ArrowComponent />
<ClassComponent />
<UI.Button />
<Button>Antd 按钮</Button> {/* 第三方库,不处理 */}
<div>原生 div</div> {/* 原生元素,不处理 */}
</div>
);
}输出代码
import React from "react";
import { Button } from "antd";
// 函数组件 - 只有根元素被添加类名
function MyButton() {
return <button className="component-mybutton">点击我</button>;
}
// 箭头函数组件 - 只有根元素被添加类名
const ArrowComponent = () => (
<div className="component-arrowcomponent">箭头函数组件</div>
);
// 类组件 - 保留现有类名,追加新类名
class ClassComponent extends React.Component {
render() {
return (
<div className="existing-class component-classcomponent">
类组件
</div>
);
}
}
// 成员表达式组件 - 智能处理命名
const UI = {
Button: () => <button className="component-ui-button">UI 按钮</button>,
};
function App() {
return (
<div className="component-app">
{/* 只有 App 组件的根元素被添加类名 */}
<MyButton />
<ArrowComponent />
<ClassComponent />
<UI.Button />
<Button>Antd 按钮</Button> {/* 第三方库组件,未处理 */}
<div>原生 div</div> {/* 原生元素,未处理 */}
</div>
);
}🔧 开发指南
环境要求
- Node.js: >= 16.0.0
- Rust: >= 1.70.0
- 目标平台: wasm32-wasip1
本地开发
# 克隆项目
git clone https://github.com/your-org/swc-plugin-component-annotate.git
cd swc-plugin-component-annotate
# 安装依赖
npm install
# 构建 WASM 文件
npm run build
# 运行测试
npm test
# 运行插件功能测试
npm run test-plugin项目结构
├── src/
│ └── lib.rs # 插件核心逻辑
├── test-rsbuild/ # 测试项目
│ ├── src/
│ │ └── index.jsx # 测试用例
│ ├── rsbuild.config.js # Rsbuild 配置
│ └── 功能验证报告.md # 功能测试报告
├── example/
│ ├── input.jsx # 示例输入文件
│ └── expected-output.jsx # 期望输出文件
├── test-plugin.js # 插件测试脚本
├── Cargo.toml # Rust 项目配置
└── package.json # NPM 包配置测试覆盖
插件经过全面测试,覆盖以下场景:
- ✅ 函数组件支持
- ✅ 箭头函数组件支持
- ✅ 类组件支持
- ✅ 成员表达式组件支持
- ✅ 根元素智能识别
- ✅ 深度嵌套处理
- ✅ React Fragment 处理
- ✅ 第三方库过滤
- ✅ 自定义前缀配置
- ✅ 现有类名保护
- ✅ 原生元素忽略
- ✅ 多根元素处理
测试通过率: 100% 🎉
🏗️ 技术实现
本插件基于 SWC 的 AST 转换能力,采用以下技术方案:
核心算法
- AST 遍历: 深度优先遍历 JavaScript/JSX 抽象语法树
- 组件识别: 通过模式匹配识别不同类型的 React 组件定义
- 导入分析: 分析 import 语句,过滤第三方库组件
- 深度跟踪: 使用栈结构跟踪 JSX 元素嵌套深度
- 类名生成: 基于组件名生成规范化的 CSS 类名
- 属性注入: 智能合并现有 className 属性
性能优化
- 编译时处理: 零运行时开销
- 增量编译: 只处理变更的组件
- 内存优化: 使用 Rust 的零成本抽象
- 并行处理: 支持多线程编译
🔗 兼容性
支持的框架和工具
- 构建工具: Rspack (>= 1.3.7), Rsbuild (>= 1.3.2)
- React 版本: React 16.8+, React 17, React 18
- TypeScript: 完全支持 TypeScript 和 JSX
- 目标环境: 现代浏览器, Node.js
版本兼容性
| 工具 | 版本要求 | |------|----------| | Rspack Core | >= 1.3.7 | | Rsbuild Core | >= 1.3.2 | | SWC Core | >= 26.0.0 | | Node.js | >= 16.0.0 |
🤝 贡献指南
我们欢迎社区贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 开启 Pull Request
开发规范
- 遵循 Rust 代码规范
- 添加相应的测试用例
- 更新相关文档
- 确保所有测试通过
📄 许可证
本项目采用 MIT License 许可证。
🙏 致谢
感谢以下项目和贡献者:
📞 支持
如果你遇到问题或有建议,请:
- 查看 FAQ
- 提交 Issue
- 参与 Discussions
