Tailwind CSS 项目配置及警告自动修复

前言

本文记录在 Vue 3 + Vite + TypeScript 项目中接入 Tailwind CSS v4 的完整步骤,并配置 Prettier + ESLint + VS Code,让 Tailwind 类名警告在保存时自动修复(排序、简写、冲突检测等)。

技术栈版本参考:

  • Tailwind CSS v4
  • @tailwindcss/vite
  • eslint-plugin-tailwindcss v4
  • prettier-plugin-tailwindcss

若项目同时使用 Ant Design Vue,建议不引入 Preflight,避免与组件库全局样式冲突。

安装依赖

统一使用 pnpm(避免与 npm 混装导致 node_modules/.ignored 警告):

1
pnpm add -D tailwindcss @tailwindcss/vite

自动修复相关:

1
2
3
pnpm add -D prettier prettier-plugin-tailwindcss \
eslint @eslint/js typescript-eslint eslint-plugin-vue vue-eslint-parser \
eslint-plugin-tailwindcss globals

package.json 中补充脚本:

1
2
3
4
5
6
7
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write ."
}
}

可选:锁定包管理器,根目录 .npmrc

1
package-manager-strict=true

package.json 中指定:

1
"packageManager": "pnpm@11.0.8"

Vite 接入 Tailwind v4

vite.config.ts 注册官方 Vite 插件:

1
2
3
4
5
6
7
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
plugins: [tailwindcss(), vue()],
})

全局样式

src/style.css

Tailwind v4 推荐在 CSS 入口文件中引入,并通过 @config 关联 JS/TS 配置文件。

与 Ant Design Vue 共存时,只引入 theme + utilities,不引入 Preflight

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/utilities" layer(utilities);
@config "../tailwind.config.ts";

@theme {
--color-brand: #36b8a7;
--color-brand-hover: #2ea890;
--color-brand-dark: #2ba08c;
--color-accent-blue: #4d9ff6;
--color-accent-teal: #45b7a4;
--color-surface-page: #f3f3f3;
--color-surface-stat: #e7edf6;
--color-surface-muted: #7f8795;
--max-width-content: 1200px;
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'PingFang SC',
'Microsoft YaHei', sans-serif;
}

*,
*::before,
*::after {
box-sizing: border-box;
}

/* 其余 body / reset 样式… */

src/main.ts 中引入:

1
import '@/style.css'

tailwind.config.ts

项目根目录创建配置文件,负责 content 扫描路径theme.extend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import type { Config } from 'tailwindcss'

export default {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
brand: {
DEFAULT: '#36b8a7',
hover: '#2ea890',
dark: '#2ba08c',
},
accent: {
blue: '#4d9ff6',
teal: '#45b7a4',
},
surface: {
page: '#f3f3f3',
stat: '#e7edf6',
muted: '#7f8795',
},
},
maxWidth: {
content: '1200px',
},
fontFamily: {
sans: [
'-apple-system',
'BlinkMacSystemFont',
'Segoe UI',
'Roboto',
'PingFang SC',
'Microsoft YaHei',
'sans-serif',
],
},
},
},
} satisfies Config

使用语义化类名示例:

1
<div class="max-w-content bg-surface-page text-brand">...</div>

@theme 中的 CSS 变量与 theme.extend 保持同步,便于在设计 token 与工具类之间统一。

Prettier:保存时自动排序 class

根目录 prettier.config.js

1
2
3
4
5
6
7
8
9
/** @type {import('prettier').Config} */
export default {
plugins: ['prettier-plugin-tailwindcss'],
tailwindStylesheet: './src/style.css',
semi: false,
singleQuote: true,
trailingComma: 'all',
printWidth: 100,
}

.prettierignore 示例:

1
2
3
dist
node_modules
pnpm-lock.yaml

命令行格式化:

1
pnpm format

ESLint:Tailwind 规则

根目录 eslint.config.js(Flat Config):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import js from '@eslint/js'
import pluginVue from 'eslint-plugin-vue'
import tailwind from 'eslint-plugin-tailwindcss'
import tseslint from 'typescript-eslint'
import globals from 'globals'

export default tseslint.config(
{
ignores: ['dist/**', 'node_modules/**', 'public/**', '.cursor/**'],
},
js.configs.recommended,
...tseslint.configs.recommended,
...pluginVue.configs['flat/essential'],
tailwind.configs.recommended,
{
files: ['**/*.{vue,js,ts,mjs}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: { ...globals.browser, ...globals.node },
},
settings: {
tailwindcss: {
cssConfigPath: 'src/style.css',
attributes: ['class', ':class', 'className'],
},
},
},
{
files: ['**/*.vue'],
languageOptions: {
parserOptions: { parser: tseslint.parser },
},
},
)

要点:

  • Tailwind v4 使用 cssConfigPath 指向 src/style.css,而不是旧的 tailwind.config.js 路径
  • tailwind.configs.recommended 启用官方推荐规则
  • 可自动修复:类名排序、简写、冲突类名等

命令行:

1
pnpm lint:fix

VS Code:保存时自动修复

.vscode/settings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript", "typescript", "vue"],
"tailwindCSS.experimental.configFile": "tailwind.config.ts",
"tailwindCSS.lint.suggestCanonicalClasses": "warning",
"tailwindCSS.validate": true,
"css.validate": false,
"tailwindCSS.includeLanguages": { "vue": "html" },
"tailwindCSS.classAttributes": ["class", "className", ":class", "ui"]
}

推荐扩展 .vscode/extensions.json

1
2
3
4
5
6
7
8
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss"
]
}

保存 .vue 文件时的执行顺序:

  1. Prettier → 排序 Tailwind class
  2. ESLint fixAll → 修复可自动修复的 Tailwind 规则

修改配置后建议 重载 VS Code 窗口

验证

1
2
3
4
pnpm dev          # 开发服务正常
pnpm run build # 构建通过
pnpm lint:fix # ESLint 自动修复
pnpm format # Prettier 格式化

在 Vue 文件中故意写乱 class 顺序,保存后应被 Prettier 自动排序;冲突类名(如同时写 p-2p-4)会由 ESLint 提示并可通过 fix 修复。

总结

层级 文件 作用
构建 vite.config.ts @tailwindcss/vite 插件
主题 tailwind.config.ts + @theme 设计 token、content 扫描
入口 src/style.css 引入 Tailwind 层、@config
排序 prettier.config.js 保存时 class 排序
校验 eslint.config.js Tailwind 规则 + --fix
编辑器 .vscode/settings.json 保存时 format + fixAll

注意

Tailwind v4 重要约定:! 后缀

v4 中 !important 修饰符写在类名末尾,不要再用 v3 的前缀写法:

1
2
3
4
5
<!-- ❌ v3 -->
<a-button class="!h-10 hover:!bg-brand" />

<!-- ✅ v4 -->
<a-button class="h-10! hover:bg-brand-hover!" />