postcss插件顺序必须为postcss-import→tailwindcss→@fullhuman/postcss-purgecss→autoprefixer→cssnano,否则css全空;purgecss须在autoprefixer后、cssnano前,且cssnano需关闭discardunused,动态类名和变体须加入safelist正则。

PostCSS插件顺序错一位,CSS就全空
构建后文件只剩 @charset "UTF-8";,或 Lighthouse 显示 “CSS 规则数为 0”,基本就是插件顺序崩了。PurgeCSS 对位置极其敏感,它必须在 tailwindcss(如有)之后、autoprefixer 之后、cssnano 之前运行。
正确顺序只能是:postcss-import → tailwindcss → @fullhuman/postcss-purgecss → autoprefixer → cssnano
-
cssnano若在 PurgeCSS 前运行,会提前合并/重写选择器(比如把.btn:hover变成.btn:is(:hover)),导致 PurgeCSS 扫不到原始类名 -
@fullhuman/postcss-purgecss若在autoprefixer前,带前缀的选择器(如.btn:-webkit-appearance)根本不会被匹配,漏删 -
cssnano必须关掉重复清理:discardUnused: { discardUnused: false },否则和 PurgeCSS 冲突,二次误删
safelist不加正则,Tailwind变体和属性选择器必丢
group-hover:text-red-500 失效、[data-state=open] 样式消失、[&_svg] 图标变空白——这些不是 PurgeCSS 没干活,而是默认提取器压根不认识这些模式。
- 必须加正则到
safelist:/^(hover|focus|group-hover|data)-/、/\[.*\]/、/\&_[^}]+/ - Tailwind 的
@layer或@apply生成的选择器,若没在源码中显式写出(比如没写class="hover:bg-blue-500"),也不会被识别,得靠正则兜底 - 启用
keyframes: true和fontFace: true,否则@keyframes和@font-face会被连带清除
content路径写错,动态类名直接被清光
用 glob.sync('./src/**/*.vue')?Windows 下路径失效,且扫的是未编译文本;class="btn {{ type }}-btn" 这种模板语法里,primary-btn 根本没出现,PurgeCSS 就当它不存在。
- 改用绝对路径:
path.join(__dirname, 'src', '**', '*.{js,ts,jsx,tsx,vue}') - Vue/React 项目务必启用
modules: true(purgecss-webpack-plugin支持 AST 解析),或换vite-plugin-purgecss(Vite 项目) - JS 注入 CSS 的插件(如
vite-plugin-css-injected-by-js)输出不在content范围内,得手动加进数组,或禁用该插件 -
devtool: 'source-map'会导致 source map 内容污染类名匹配,生产环境务必关掉
Tailwind项目额外装@fullhuman/postcss-purgecss等于白配
Tailwind v3+ 自带 Purge 功能,和 @fullhuman/postcss-purgecss 是两套独立逻辑,同时启用必然冲突:一个删完,另一个再扫一遍,结果更不可控。
- 删掉
postcss.config.js里多余的@fullhuman/postcss-purgecss插件 - 改用 Tailwind 原生
content配置,支持defaultExtractor和transformers,对[data-role]、className={`modal ${isOpen ? 'is-open' : ''}`更友好 - 第三方库(如 Bootstrap、Ant Design)的类名不会自动被识别,必须手动进
safelist,例如:['ant-btn', /^btn-/, /^modal-/]
safelist 或 AST 解析来保活——尤其当类名来自 API、计算属性、或运行时拼接时,字符串匹配天然失效。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











