PurgeCSS删掉已用class的根本原因是它仅识别静态字符串字面量,无法处理动态拼接、JS注入或模板字符串中的类名;必须通过safelist显式声明动态类模式或确保源码中完整出现。
PurgeCSS 不是误判,而是根本没“看见”那些类名。它只扫描源码中静态出现的字符串字面量,比如 class="btn active" 或 className="text-red-500";对 className={`btn-${type}`}、el.classList.add('hidden')、甚至 :class="['icon-' + name]" 这类运行时拼接或 JS 注入的写法,它完全不处理——不是不想,是做不到。
别指望 PurgeCSS 自动推导模板字符串结果。最可靠的方式是把已知模式直接写进 safelist,它优先级最高,且不依赖文件扫描路径是否覆盖到位。
/^text-(red|blue|green)-[0-9]{3}$/ 保留下划线色值类"md:text-*"、"hover:opacity-*"
{ pattern: /^(?:md|hover):text-(?:red|blue)-(?:500|600)$/ }
/text-.*/ 这种宽泛正则——它可能意外保留 text-clip 这类原生属性很多人以为只要 content: ['./src/**/*.{js,jsx,ts,vue}'] 就万事大吉,但问题常出在:Vue 单文件组件里的 <div :class="xxx">、React 中的 JSX 模板字符串,原生提取器根本不会解析 AST,只当普通文本扫一遍,变量部分直接被跳过。
purgecss-webpack-plugin 扫的是原始 .vue 文件,不是编译后的 JS,所以 class="btn-{{ type }}" 这种写法压根不会被识别vite-plugin-purgecss 默认不处理 import.meta.glob 动态导入的模块,这些模块里的 class 字符串得手动加进 content 数组<MyButton class="custom-btn">)若来自 props 或 JSON 配置,也必须进 safelist
构建后样式消失,第一反应不该是改配置,而是确认 PurgeCSS 究竟干了什么。
立即学习“前端免费学习笔记(深入)”;
tailwind.config.js 加 debug: true(v3.3+),构建日志会列出 preserved 和 discarded 的类名content 字段再 build 一次——如果样式全回来了,就是 100% purge 误删npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify --content "./src/**/*.{js,ts,jsx,tsx}",绕过构建工具封装干扰真正容易被忽略的点是:PurgeCSS 匹配的是你写的源码字符串,不是浏览器最终渲染出的 DOM class。哪怕你在控制台看到 class="bg-blue-500",只要这串字符没以完整形式出现在某个 .js 或 .vue 文件里,它就大概率被清掉。