PurgeCSS无法识别:class="btn-${type}"中的btn-primary,因为它不执行JavaScript或解析模板语法,仅提取源码中字面量出现的类名字符串,而btn-${type}在静态扫描中仅为模板字符串,非运行时生成的具体类名。

为什么PurgeCSS根本看不到:class="`btn-${type}`"里的btn-primary
PurgeCSS 不执行 JavaScript,也不解析模板语法;它只做一件事:在你指定的文件里,用正则或 AST 提取所有 class 属性值中**字面量出现的字符串**。遇到 :class="`btn-${type}`",它提取到的是 btn-${type} 这个模板字符串,而不是运行时拼出的 btn-primary。所以这个类名压根不会进“已使用”列表,直接被判定为未使用。
- Vue SFC 中
v-bind:class、:class、class="text-{{ color }}"(Options API)全属此类 - React 的
className={`modal ${isOpen ? 'is-open' : ''}`}同理——源码里只有is-open这个字符串?没有。那它就被删 - 哪怕你在
setup()里返回一个 computed class 字符串,只要没在模板/JSX 中作为字面量出现,PurgeCSS 就当它不存在
content 配置漏路径,等于主动放弃扫描权
你以为 content: ['./src/**/*.vue'] 就够了?错。PurgeCSS 只扫你列出来的路径下**实际存在的文件内容**,且只认你写的字面量。如果动态 class 来自:
-
src/composables/useButton.ts里定义的const btnClass = computed(() => `btn-${props.type}`)—— 这个 TS 文件没进content,里面的btn-字符串就完全不可见 -
public/config.json里存着"class": "bg-blue-500"—— JSON 文件不在content列表里,照样删 - Vite 的
import.meta.glob动态导入组件,其路径不会被 glob 自动递归捕获,得手动加进content - 第三方库(如 DaisyUI)的 class 写在
node_modules/daisyui/dist/index.js里?默认不扫,必须显式加路径或靠safelist
safelist 正则写错,等于白加
写了 /btn-/,结果 btn-primary 没保住?因为正则没锚定边界,/btn-/ 会匹配 btn-clip(原生 CSS 属性),但 PurgeCSS 实际要求的是完整类名匹配。更常见错误:
- 漏变体前缀:
md:btn-primary和hover:btn-primary是独立字符串,需单独覆盖,例如/^(?:md|hover):btn-(?:primary|danger)$/ - 用了捕获组
(md|hover)而非非捕获组(?:md|hover),导致正则语法错误,整个 pattern 失效 - 写
/text-.*/这种宽泛模式,意外保留text-clip、text-overflow,还可能干扰其他插件 - 函数式 pattern 写成
{ pattern: /text-(red|blue)-\d+/ }是对的,但若 color 值来自 CMS 或 JSON,就得额外把具体字符串(如text-red-500)也塞进safelist
Tailwind v3+ 内置 Purge 和外部 PurgeCSS 插件打架
如果你在 tailwind.config.js 里配了 content,又在 postcss.config.js 里手动加了 @fullhuman/postcss-purgecss,两者会重复扫描、互相干扰。典型症状:
立即学习“前端免费学习笔记(深入)”;
- 构建后 CSS 文件只剩
@charset "UTF-8"; - Lighthouse 显示 “CSS 规则数为 0”
- PostCSS 插件顺序错位(比如
purgecss在tailwindcss前运行),导致 Tailwind 还没生成完整类名,PurgeCSS 就开始删了
正确做法:Tailwind 项目直接删掉 @fullhuman/postcss-purgecss,只用 tailwind.config.js 的 content + safelist,并确保 PostCSS 配置里 tailwindcss 在 purgecss 类插件之前(其实不该有)。


















