Tailwind v3默认打包体积大是因为未正确配置content路径导致JIT失效,从而全量打包工具类。必须在tailwind.config.js中设置有效的content数组,覆盖所有含class的文件(如src/*/.{js,ts,jsx,tsx,html,vue}),路径不能留空、注释或错误,否则退化为伪JIT,CSS体积常超2MB。

为什么Tailwind v3默认打包体积大
因为v3默认仍启用purge(已废弃),但若没配content或路径写错,它就无法安全删除未用类,最终把整个工具类集合打进CSS——体积常超2MB。这不是JIT没开,而是JIT依赖content配置才能知道“哪些类真被用了”。
必须开启JIT并正确配置content路径
JIT模式在v3中已是默认,但仅当content字段存在且路径有效时才真正生效。漏配、路径通配错误、或指向了不存在的文件,都会退化为全量扫描(即“伪JIT”)。
-
tailwind.config.js里必须有content数组,不能留空或注释掉 - 路径要覆盖所有可能写class的地方:
src/**/*.{js,ts,jsx,tsx,html,vue}(Vue项目加.vue,Svelte加.svelte) - 避免写
./src/**/*.tsx——./在某些构建工具下不识别,统一用src/**/*.{...} - 如果用Vite或Next.js,确保路径包含
index.html和_app.tsx等顶层入口,否则dark:、group-等上下文类可能被误删
常见content配置错误导致的体积反弹
即使开了JIT,以下情况仍会产出接近全量的CSS:
-
content: ["./src/**/*.{js,ts}"]—— 漏了jsx/tsx,JSX中写的class全被忽略,JIT无从推断,只好保守保留全部 -
content: ["src/App.tsx"]—— 只写单个文件,子组件、Layout、甚至className拼接字符串(如class={`${base} ${isDone ? 'text-green-500' : ''}`)都无法被静态分析到 -
content: ["public/**/*.html"]—— 但实际class全在JSX里,HTML里根本没class,等于没配 - 使用
eval()或dangerouslySetInnerHTML动态注入class,JIT无法静态分析,需用/* eslint-disable tailwindcss/no-custom-classname */或!important兜底,但体积控制失效
验证JIT是否真正生效
别只看打包后CSS体积数字,要确认删减逻辑跑对了:
立即学习“前端免费学习笔记(深入)”;
- 运行
npm run build后,检查输出CSS里是否还有bg-gradient-to-r、first-letter:text-xl这类冷门类——如果大量存在,说明content没扫到使用处 - 临时在某个
.tsx文件里加一行className="bg-hotpink text-9xl"(非法值),再构建:JIT正常时会忽略(因无匹配类),但若CSS里真出现了bg-hotpink,说明它根本没走JIT,还在全量打包 - Vite用户可在
vite.config.ts里加build.rollupOptions.output.manualChunks拆包,配合rollup-plugin-visualizer看CSS chunk构成,确认tailwind.css是否稳定在100KB内
最易被忽略的是:框架特定语法(如Next.js的app/目录、Astro的.astro组件)必须显式加入content路径,少一个扩展名,就少一片可删减的类。


















