Skip to main content
vanilla-extract 帮助将项目样式迁移到 vanilla-extract (@vanilla-extract/css)。当需要在 Vite + React 项目中:添加 vanilla-extract、把 `.css`/`.scss`/行内样式迁移为 `*.css.ts`、建立 design tokens/sprinkles、或为样式添加测试与规范时使用。
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/ymsjl/page-scaffold-builder --skill vanilla-extractThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository Related occupations
SOC
Based on SOC occupation classification
name vanilla-extract description 帮助将项目样式迁移到 vanilla-extract (@vanilla-extract/css)。当需要在 Vite + React 项目中:添加 vanilla-extract、把 `.css`/`.scss`/行内样式迁移为 `*.css.ts`、建立 design tokens/sprinkles、或为样式添加测试与规范时使用。
概述
提供迁移策略、示例代码、以及可执行的辅助脚本,用于把现有 CSS(外部样式表、组件级样式、以及 React 行内样式)逐步转换为 vanilla-extract 的推荐模式(静态、零运行时、类型安全的 CSS-in-TS)。
包含内容(捆绑资源)
references/vanilla-extract-usage.md — 快速使用与 API 摘要
references/migration-guidelines.md — 分步迁移计划与最佳实践
scripts/scan-styles.js — 扫描项目中需迁移的样式并生成报告
scripts/generate-css-ts-templates.js — 从 .css 文件自动生成 *.css.ts 模板(半自动、需人工补全)
触发条件(何时使用本 Skill)
需要把整个仓库或某些组件从 CSS / 行内样式 迁移到 vanilla-extract。
需要一个可重复的迁移计划、检测/报告工具或示例转换。
需要在 Vite 项目中正确配置 @vanilla-extract/vite-plugin 与测试支持。
快速使用
运行扫描:
node .agents/skills/vanilla-extract/scripts/scan-styles.js --path apps/web/src
生成模板(可选):
node .agents/skills/vanilla-extract/scripts/generate-css-ts-templates.js path/to/file.css
按 references/migration-guidelines.md 的步骤逐步迁移并补全生成的 .css.ts 模板。
要我做的事情(示例)
全仓库扫描并输出迁移优先级报告(自动)。
把指定的组件或文件从 .css / 行内样式 迁移为 *.css.ts(逐文件/批量迁移)。
添加 tokens / sprinkles 目录并重构共享样式。
内联样式迁移指南
样式分类与迁移决策
迁移内联样式时,需要识别样式类型并决定是否迁移:
✅ 应该迁移(静态样式)
这些内联样式应该提取到 .css.ts 文件:
静态样式常量
: . = {
: ,
: ,
: ,
};
<div style={TOOLBAR_STYLE}>
// ✅ 迁移后
// styles.css.ts
export const toolbar = style({
position: 'fixed',
bottom: 72,
zIndex: 20,
});
// Component.tsx
<div className={styles.toolbar}>
const
TOOLBAR_STYLE
React
CSSProperties
position
'fixed'
bottom
72
zIndex
20
重复的通用样式
<Space direction="vertical" style={{ width : "100%" }}>
<AutoComplete style={{ width: "100%" }}>
<Flex style={{ width: "100%" }}>
// ✅ 迁移后 - 提取为共享类
export const fullWidth = style({ width: '100%' });
<Space className={styles.fullWidth}>
<AutoComplete className={styles.fullWidth}>
静态布局样式
<div style={{ cursor : "grab" , display : "flex" , alignItems : "center" }}>
export const dragHandle = style ({
cursor : 'grab' ,
display : 'flex' ,
alignItems : 'center' ,
});
静态定位样式
<Handle style={{ left : "30%" }} />
export const handleTopLeft = style ({ left : '30%' });
<Handle className ={styles.handleTopLeft} />
⚠️ 应该保留(动态样式)
基于 props/state 的动态值
<div style={{ paddingLeft : `${level * 8 } px` }}>
<div style={{ borderColor: color }}>
<div style={{ background: enabled ? undefined : "#fafafa" }}>
第三方组件的 style props
<ProCard bodyStyle={{ padding : '16px' }} />
<Modal overlayInnerStyle ={{ borderRadius: 8 }} />
<ProFormText fieldProps ={{ style: { width: "100 %" } }} />
拖拽库的 transform 样式
const style = {
transform : CSS .Transform .toString (transform),
transition,
opacity : isDragging ? 0.5 : 1 ,
};
<div style ={style} >
常见迁移模式
1. 组件生态系统批量迁移 当多个相关组件共享样式时,创建统一的 .css.ts 文件:
export const fullWidth = style ({ width : '100%' });
export const deleteButton = style ({
background : 'none' ,
border : 'none' ,
cursor : 'pointer' ,
});
export const canvasCard = style ({ minHeight : 260 });
import * as styles from './RuleBuilder.css' ;
2. 扩展现有样式文件
export const setAsPkButton = style ({ });
export const actionsRow = style ({ marginBottom : 12 });
export const fullWidth = style ({ width : '100%' });
3. 父子悬停模式
export const wrapper = style ({ });
export const actions = style ({
visibility : 'hidden' ,
selectors : {
[`${wrapper} :hover &` ]: {
visibility : 'visible' ,
},
},
});
4. 全局样式处理 import { globalStyle } from '@vanilla-extract/css' ;
export const setAsPkButton = style ({ visibility : 'hidden' });
globalStyle (`.ant-table-cell:hover .${setAsPkButton} ` , {
visibility : 'visible' ,
});
迁移工作流
扫描与分析
node .agents/skills/vanilla-extract/scripts/scan-styles.js
读取并分类
检查每个文件中的 style={ 使用
区分静态样式 vs 动态样式
识别可复用的通用模式
创建或扩展 .css.ts
优先扩展同目录已有的 .css.ts 文件
为组件生态创建共享样式文件
使用语义化的导出名称
批量更新组件
验证与测试
pnpm --filter ./apps/web test -- --run
常见静态内联样式速查表 原始内联样式 推荐类名 vanilla-extract 定义 style={{ width: "100%" }}className={styles.fullWidth}width: '100%'style={{ marginBottom: 12 }}className={styles.actionsRow}marginBottom: 12style={{ cursor: "pointer" }}className={styles.clickable}cursor: 'pointer'style={{ minHeight: 260 }}className={styles.canvasCard}minHeight: 260style={{ borderRadius: 8, padding: 4 }}className={styles.container}{ borderRadius: 8, padding: 4 }style={{ fontSize: 12, display: "block" }}className={styles.message}{ fontSize: 12, display: 'block' }
实际迁移案例
案例 1:工具栏样式常量
文件 : ComponentPreview.tsx
迁移内容 : TOOLBAR_STYLE、TOOLBAR_CONTAINER_STYLE 常量
方法 : 添加到现有 previewStyles.css.ts
收益 : 移除 2 个样式常量,类型检查更安全
案例 2:组件生态批量迁移
文件 : RuleBuilder.tsx、RuleCanvas.tsx、RuleItem.tsx
迁移内容 : 创建新的 RuleBuilder.css.ts 统一管理
方法 : 提取通用样式(fullWidth、deleteButton 等)
收益 : 3 个组件共享 5 个样式类,减少重复代码
案例 3:拖拽组件样式
文件 : SchemaList.tsx
迁移内容 : 拖拽手柄、图标样式
保留 : dnd-kit 的 transform 和 transition(动态)
方法 : 静态定位和视觉样式迁移,动态 transform 保留
迁移进度追踪
cssFiles: 9, inlineStyleFiles: 25, cssImports: 9
cssFiles: 0, inlineStyleFiles: 13, cssImports: 2
- 所有外部 CSS 文件已迁移 ✅
- 静态内联样式减少 48% (25 → 13)
- 剩余主要为动态样式和第三方组件 props
最佳实践与注意事项
✅ 推荐做法
优先扩展而非新建
同一组件目录下已有 .css.ts 时,扩展它而不是创建新文件
减少文件数量,便于维护
语义化命名
使用描述用途的名称:toolbar、dragHandle、actionsRow
避免样式值作为名称:marginBottom12、width100
共享通用样式
多次使用的样式提取为共享类:fullWidth、clickable
在组件生态内共享样式文件
渐进式迁移
先迁移静态样式,保留动态样式
从简单组件开始,逐步处理复杂组件
每次迁移后立即测试
使用批量操作
相关文件一起迁移(如 RuleBuilder 生态的 3 个文件)
使用 multi_replace_string_in_file 提高效率
❌ 避免事项
不要迁移动态样式
<div style={{ paddingLeft : `${level * 8 } px` }}>
不要移除第三方组件的 style props
<ProFormText fieldProps={{ style : { width : "100%" } }} />
不要在 .css.ts 中使用运行时值
export const dynamic = style ({
color : props.color ,
});
不要过度拆分样式
export const mb2 = style ({ marginBottom : 2 });
export const mb4 = style ({ marginBottom : 4 });
export const mb8 = style ({ marginBottom : 8 });
export const cardGap = style ({ marginBottom : 8 });
选择器模式参考 export const wrapper = style ({ position : 'relative' });
export const actions = style ({
visibility : 'hidden' ,
selectors : {
[`${wrapper} :hover &` ]: { visibility : 'visible' },
},
});
<div className ={wrapper} >
<div className ={actions} > ...</div >
</div >
import { globalStyle } from '@vanilla-extract/css' ;
export const button = style ({ visibility : 'hidden' });
globalStyle (`.ant-table-cell:hover .${button} ` , {
visibility : 'visible' ,
});
故障排除
检查 vite.config.ts 是否正确配置 @vanilla-extract/vite-plugin
确认 .css.ts 文件在 Vite 处理范围内
查看浏览器开发工具,确认类名已生成
selectors : {
'&:hover ${other}' : { ... }
}
selectors : {
[`${parent} :hover &` ]: { ... }
}
vanilla-extract 样式是编译时生成的字符串
不要尝试将 .css.ts 导出用作 React.CSSProperties
只能作为 className 使用
性能优化
避免过多的全局样式
globalStyle 会增加 CSS 体积
优先使用组合和选择器
复用 token
从 @/styles/tokens.css 导入设计 token
保持样式一致性
按需导入
import * as styles from './Component.css' ;
import { style1, style2, style3 } from './Component.css' ;
快速参考
迁移决策流程图 发现内联样式 style={...}
↓
是否为静态值?
├─ 是 → 是否重复使用?
│ ├─ 是 → 提取为共享类 (fullWidth, clickable)
│ └─ 否 → 提取为组件专用类 (toolbar, header)
│
└─ 否 → 是否依赖运行时变量?
├─ 是 (props/state) → 保留内联 ✅
├─ 第三方组件 props → 保留内联 ✅
└─ 拖拽库 transform → 保留内联 ✅
常用命令速查
node .agents/skills/vanilla-extract/scripts/scan-styles.js
cat .vanilla-extract-scan.json
pnpm --filter ./apps/web test -- --run
pnpm --filter ./apps/web dev
快速模板
import { style } from '@vanilla-extract/css' ;
export const container = style ({
});
export const fullWidth = style ({
width : '100%' ,
});
import * as styles from './Component.css' ;
export const Component = ( ) => (
<div className ={styles.container} >
<div className ={styles.fullWidth} > ...</div >
</div >
);
export const newStyle = style ({
});
迁移检查清单
关键文件位置 project-root/
├── .vanilla-extract-scan.json # 扫描结果报告
├── .agents/skills/vanilla-extract/ # Skill 目录
│ ├── SKILL.md # 本文档
│ ├── references/ # 参考文档
│ └── scripts/ # 辅助脚本
└── apps/web/src/
├── styles/
│ └── tokens.css.ts # 设计 token
└── components/
└── YourComponent/
├── YourComponent.tsx # 组件文件
└── YourComponent.css.ts # 样式文件