Tailwind CSS打包未清除未用样式,根本原因是JIT模式未启用:必须同时满足生产模式(--minify或TAILWIND_MODE=build)、content路径全覆盖(如"./src/*/.{js,jsx,ts,tsx}")及PostCSS插件链完整生效。

Tailwind CSS 打包时未清除未用样式,基本就是 JIT 模式根本没跑起来——它不是“默认裁剪”,而是必须满足三个硬条件:生产模式、正确 content 路径、且 PostCSS 插件链完整生效。
为什么 TAILWIND_MODE=build 或 --minify 缺一不可
Tailwind 的 purge 行为只在明确进入生产构建流程时触发。开发服务器(npm run dev)走的是 JIT 实时生成,完全绕过 content 扫描;而直接执行 npx tailwindcss -i input.css -o output.css 默认是“开发模式”,哪怕文件名带 .prod.css 也没用。
- 必须显式启用:加
--minify参数,或设环境变量TAILWIND_MODE=build - Next.js/Vite 等框架封装了这层逻辑,但如果你手写 CLI 命令或自定义 Webpack 构建,漏掉就等于全量输出
- 验证方式:
grep -o "text-lg" dist/output.css | wc -l对比源码中出现次数,若几乎不变,说明 JIT 未启动
content 路径没覆盖到真实类名位置
Tailwind v3+ 不再猜路径,只扫描 content 数组里字面量匹配的文件。漏一个扩展名、少一层 **、大小写不一致,对应类名就进不了扫描范围,自然不会被裁剪——更糟的是,它可能因扫描失败而退化为保守全量输出。
- React + TSX 必须写成
"./src/**/*.{js,jsx,ts,tsx}",不能只写.js或漏掉jsx - Next.js App Router 需同时包含
"app/**/*.{js,ts,jsx,tsx}"和"components/**/*.{js,ts,jsx,tsx}" - Vite 项目要加
"./index.html",public 下的 HTML 也得手动列进去 - 用
raw-loader加载的 HTML?路径必须进content,例如"./src/**/*.html"
PostCSS 插件没加载或顺序错乱
@tailwind 指令只是注释,除非 PostCSS 真正调用了 Tailwind 插件,否则整段 CSS 就是纯文本。常见断点:
立即学习“前端免费学习笔记(深入)”;
- Vite 用户:检查
postcss.config.js是否是require('@tailwindcss/postcss'),不是旧版require('tailwindcss') - Webpack 用户:确认
postcss-loader在css-loader之前,且css-loader的modules选项没开启(开启后类名被哈希化,和 Tailwind 输出不匹配) - CRA 用户:默认禁用自定义 PostCSS,需用
craco注入插件,或eject
动态类名导致扫描器“看不见”真实使用
像 className={`text-${color}-500`} 这种写法,源码里根本没有 text-red-500 这个字符串,PurgeCSS 就当它不存在。这不是 bug,是设计上拒绝为运行时拼接兜底。
- 高频组合建议预定义对象:
const textClasses = { error: 'text-red-500', success: 'text-green-500' } - 必须用正则 safelist 时,写成
{ pattern: /text-(red|green|blue)-500/ },别写成字符串'/text-(red|green)-500/' - 响应式前缀要显式带上:
/^(md|lg):text-(red|blue)-500$/,否则md:text-red-500会被漏掉
最易被忽略的一点:你改了 tailwind.config.js 却没重启开发服务器——Node.js 缓存模块,PostCSS 插件读的还是旧配置,content 路径压根没更新。



















