tailwind css v3+ 必须用content字段替代purge,精确覆盖所有含class的文件路径(如.vue/.tsx),并配合框架感知插件(如vite-plugin-purgecss)和绝对路径写法,否则构建时无法扫描到类名。

Webpack 5+ 或 Vite 升级后 content 扫不到 .vue/.tsx 文件
升级构建工具后,content 配置里写的 ./src/**/*.{vue,ts,tsx} 可能根本没扫到任何 class 字符串——因为新版本的 loader(如 @vitejs/plugin-vue 或 vue-loader@17+)默认在 PostCSS 运行前就把 <template></template> 编译成 JS 字符串或 AST,PurgeCSS 插件看到的只是原始模板文本(比如 class="btn {{ type }}"),压根提取不出 btn-primary。
必须改用框架感知型插件:
- Vite 项目:删掉
@fullhuman/postcss-purgecss,换vite-plugin-purgecss(它在 Rolluptransform钩子中运行,能拿到编译后的 class 字符串) - Webpack 项目:用
purgecss-webpack-plugin并启用modules: true(支持 AST 解析),别手写new PurgeCSSPlugin() - 路径写法必须用绝对路径:
path.join(__dirname, 'src', '**', '*.{js,ts,jsx,tsx,vue}'),硬写./src/**/*在 Windows 下会因分隔符失效
PostCSS 插件顺序错位导致 CSS 被二次清空
旧配置可能把 @fullhuman/postcss-purgecss 放在 cssnano 后面,而新版本 cssnano 默认开启 discardUnused: true。结果是 PurgeCSS 删一遍,cssnano 再删一遍——连带把已保留的类对应声明也合并/丢弃了,最终 CSS 文件只剩 @charset "UTF-8";。
正确顺序(不可颠倒):
postcss-import-
tailwindcss(如有) @fullhuman/postcss-purgecssautoprefixer-
cssnano,且显式关掉重复清理:{ discardUnused: false }
Tailwind v3+ 升级后 purge 字段被忽略
如果你从 Tailwind v2 升到 v3+,purge: [] 字段已废弃,必须改成 content: []。但很多人只改了字段名,忘了检查内容是否覆盖真实输出路径——比如 Vite 构建后 .vue 文件不进 dist,你却还在 content 里写 ./dist/**/*.html,等于白配。
还要注意:
- 第三方组件库的类(如
react-datepicker__day)不会出现在你自己的源码里,得手动加进safelist或显式扫描node_modules/react-datepicker/**/*.{js,ts} - 动态变体如
hover:bg-blue-500、group-hover:text-red-500默认不识别,safelist得加正则:/^(hover|focus|group-hover|data)-/ - 用了
vite-plugin-css-injected-by-js?它的 JS 注入 CSS 不在content范围内,要么禁用,要么手动把注入逻辑的 JS 路径加进content
source-map 开启导致类名匹配失败
某些构建工具升级后默认开启 devtool: 'source-map',PurgeCSS 会把 source map 的 base64 字符串当作文本内容扫描,干扰 class 提取逻辑,甚至把 text-xl 错误匹配成 text-xlaG9tZS5qcw== 这种乱码。
解决方案很直接:
- 生产环境构建时关掉 source map:
devtool: false或devtool: 'hidden-source-map' - 如果必须保留 source map,确保
purgecss插件在SourceMapDevToolPlugin之后运行(Webpack)或使用vite-plugin-purgecss(Vite 自动处理)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











