PurgeCSS 无法识别 Vue 中动态生成的 class 名,因其仅扫描源码字符串而不解析运行时拼接结果;需通过 safelist 正则显式保留如 /^btn-(primary|danger|success)$/ 等匹配项,并确保 content 配置覆盖所有含动态 class 的文件路径。

动态类名在 Vue 里被 PurgeCSS 删掉,不是 Vue 的问题,也不是你写错了,而是 PurgeCSS 默认只扫描源码字符串,根本看不到 v-bind:class 或 :class 里运行时拼出来的结果。
Vue 模板中 :class 动态绑定的 class 不会被自动识别
PurgeCSS 解析的是 .vue 文件里的纯文本,比如 <div :class="`btn btn-${type}`">,它只会看到 <code>btn 和 btn-${type} 这两个字符串,而 ${type} 是 JS 变量,不会展开。所以除非你显式告诉它哪些 pattern 要保留,否则 btn-primary、btn-danger 全部可能消失。
- 不要指望
content: ["src/**/*.vue"]自动覆盖所有可能的拼接结果 - 模板里用
v-for渲染带 class 的列表,且 class 来自数组或对象字段(如item.class),这些字符串也不会被静态提取 - 使用
defineComponent+setup()返回的响应式 class 字符串,同样属于“运行时生成”,必须进safelist
safelist 中正则必须匹配最终渲染出的 class 名,不是模板里的占位符
你写 /^btn-(primary|danger|success)$/,PurgeCSS 才会保留 btn-primary 这三个;但如果你漏了 btn-warning,它就没了。更麻烦的是响应式前缀和变体——md:btn-primary 和 hover:btn-primary 是独立的 class 名,得单独匹配。
- 正确写法:
/^(?:md|hover|focus):btn-(?:primary|danger|success)$/ - 错误写法:
/btn-.*/—— 会意外保留btn-clip(原生 CSS 属性)或btn-group(第三方库类) - 如果 class 来自 JSON 配置项(如
config.buttons.map(b => b.class)),建议用函数式safelist:{ pattern: /btn-(primary|danger)/ }
Vue SFC 的 <script setup></script> 和组合式 API 类名需额外注意路径覆盖
Tailwind v3+ 的 content 配置不递归解析 import,只读你列出来的文件。哪怕你在 composables/useButton.ts 里定义了 const classes = computed(() => `btn-${props.type}`),只要这个 TS 文件没被 content glob 匹配到,里面的字符串就不会进扫描范围。
审查 Vue 管理后台的变更请求(Vue 2 + Element UI,Vue 3 + Element Plus)。重点关注最小化变更实现、上线风险检查以及回归检查清单生成。
立即学习“前端免费学习笔记(深入)”;
- 确保
content包含所有含动态 class 的文件类型:src/**/*.{vue,ts,js,jsx,tsx} - 用
import.meta.glob动态导入的组件(如路由级异步组件),其路径不会被 glob 自动捕获,得手动加进content数组 - 验证方法:临时注释掉
content字段,跑一次 build;如果样式全回来了,就是配置漏了来源
最常被忽略的一点:PurgeCSS 匹配的是源码里「作为类名出现的字符串」,不是浏览器里 DOM 上最终的 class 属性值。你在控制台看到 class="btn-primary",不代表 PurgeCSS 知道它该留——它只认你代码里写死的、或能被正则抓到的那部分。

















