Tailwind CSS 体积大主因是JIT未生效:content路径漏配(如Next.js需同时覆盖app//与pages//)、未走生产构建验证、动态类名未兜底;必须用TAILWIND_MODE=build生成并grep验证裁剪效果。

Tailwind CSS 生成的 CSS 文件体积大,不是框架本身臃肿,而是 JIT 模式没真正生效——绝大多数情况是 content 路径漏配、没走生产构建,或动态类名没兜底。
检查 content 是否覆盖所有含 class 的文件
路径漏一个,JIT 就退化为全量输出,且不报错。Next.js 项目必须同时包含:
app/**/*.{js,ts,jsx,tsx}pages/**/*.{js,ts,jsx,tsx}
常见错误:
- 只写
src/**/*.tsx,漏掉.jsx或.html(如 MDX、EJS 模板) - 用
./src/**,Vite 可能解析失败;统一用src/**/*.{js,jsx,ts,tsx,html} - SSR/静态生成的模板路径(如
data/**/*.mdx)没加进content,服务端渲染出的 class 会被当“死代码”删掉
验证 JIT 是否真在工作
别信本地 npm run dev 的表现——开发服务器是实时生成,完全绕过 content 扫描。
立即学习“前端免费学习笔记(深入)”;
必须用生产模式验证:
- 运行:
TAILWIND_MODE=build npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify - 在某个被
content覆盖的文件里加一个冷门但合法的类,比如bg-hotpink - 执行:
grep -o "bg-hotpink" ./dist/output.css—— 如果返回非空,说明 JIT 根本没跑 - 再查高频类:
grep -o "text-lg" ./dist/output.css | wc -l,对比源码中出现次数,显著减少才代表裁剪有效
动态类名(如 text-${color})必须显式兜底
Tailwind 不执行 JS,只匹配字面量字符串。所以 text-${color} 这种写法,在构建时会被当成未使用类直接剔除。
安全做法分三类:
- 颜色/尺寸等可枚举:在
tailwind.config.js的safelist中写正则,例如/^text-(red|blue|green)-500$/(结尾加$防误匹配) - 避免宽泛正则:
/^text-/会保住全部text-类,等于放弃 tree-shaking - 优先改用
@apply封装:.text-status-error { @apply text-red-500; },并确保该 CSS 文件路径已加入content
别用 PurgeCSS 插件重复清理
Tailwind v3+ 内置 JIT + Purge 逻辑,额外装 @fullhuman/postcss-purgecss 不仅无效,还会因 PostCSS 插件顺序错乱导致产出为空或误删。
真正要配的是:
-
safelist必须包含状态类前缀:/^(hover|focus|group-hover|peer-checked|data)-/ -
postcss.config.js中tailwindcss插件必须在cssnano之前,否则压缩会破坏 JIT 生成的选择器结构 - 如果用了
cssnano,它能进一步合并相同规则、简化颜色和单位,但不能替代 JIT 的类级裁剪
最常被忽略的一点:JIT 是否生效,和你写了多少 @apply、用了多少组件库完全无关——它只认 content 路径是否真实扫到了所有 class 字面量。路径一漏,2MB CSS 就安静地躺在 dist 里,连 warning 都不会给你。


















