这是前后端混合仓库的完整方案:Prettier 管所有格式,ESLint 管 JS/TS 质量,Stylelint 只管 CSS 语法/语义、不管排版。
一、分工(一张表记牢)
| 工具 | 管什么 | 不管什么 |
|---|---|---|
Prettier(.prettierrc) | JS / TS / TSX / JSON / CSS / SCSS / MD 等排版 | 代码质量、CSS 语义 |
| ESLint | JS / TS / TSX质量(未使用变量、hooks、Promise…) | 缩进、引号、分号、CSS |
| Stylelint | CSS / SCSS语法与语义(非法属性、未知伪类、重复选择器等) | 缩进、换行、空格(交给 Prettier) |
保存文件 ├─ Prettier → 按 .prettierrc 排版(含 .css) ├─ ESLint fix → 修 TS/JS 质量问题 └─ Stylelint fix → 修 CSS 可自动修的质量问题(不碰 Prettier 管的格式) CI ├─ prettier --check ├─ eslint └─ stylelint二、依赖(根package.json)
{"devDependencies":{"prettier":"^3.4.2","eslint":"^9.18.0","@eslint/js":"^9.18.0","eslint-config-prettier":"^10.0.1","typescript-eslint":"^8.20.0","globals":"^17.0.0","stylelint":"^16.0.0","stylelint-config-standard":"^36.0.0","stylelint-config-prettier":"^9.0.0"}}前端 React 再按需加:eslint-plugin-react-hooks、eslint-plugin-react-refresh
用 SCSS 可把stylelint-config-standard换成stylelint-config-standard-scss。
不要装eslint-plugin-prettier(格式不经过 ESLint)。
必须装eslint-config-prettier、stylelint-config-prettier(关掉和 Prettier 冲突的规则)。
三、.prettierrc(全仓库唯一格式真相)
{"singleQuote":true,"trailingComma":"all","semi":true,"printWidth":100,"tabWidth":2,"useTabs":false,"endOfLine":"lf","arrowParens":"always","bracketSpacing":true}CSS 保存格式化也读这一份,不要在 Stylelint 里配缩进/换行。
四、.prettierignore
node_modules dist build coverage .next .output generated *.min.css pnpm-lock.yaml package-lock.json五、.vscode/settings.json
{"editor.formatOnSave":true,"editor.defaultFormatter":"esbenp.prettier-vscode","editor.codeActionsOnSave":{"source.fixAll.eslint":"explicit","source.fixAll.stylelint":"explicit"},"[typescript]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[typescriptreact]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[javascript]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[javascriptreact]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[json]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[jsonc]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[css]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[scss]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"[markdown]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"css.validate":false,"scss.validate":false,"less.validate":false,"stylelint.validate":["css","scss"],"stylelint.snippet":["css","scss"],"files.eol":"\n","files.insertFinalNewline":true,"files.trimTrailingWhitespace":true,"eslint.useFlatConfig":true,"eslint.workingDirectories":[{"mode":"auto"}]}说明:
| 配置 | 作用 |
|---|---|
CSS 的defaultFormatter= Prettier | CSS格式只走 Prettier |
css.validate: false | 关掉 VS Code 自带 CSS 检查,避免和 Stylelint 重复 |
stylelint.validate | CSS语法/语义由 Stylelint 报波浪线 |
不写prettier.* | 格式只读.prettierrc |
六、.vscode/extensions.json
{"recommendations":["esbenp.prettier-vscode","dbaeumer.vscode-eslint","stylelint.vscode-stylelint"]}七、eslint.config.mjs(只做 JS/TS 质量)
// @ts-checkimporteslintfrom'@eslint/js';importeslintConfigPrettierfrom'eslint-config-prettier';importglobalsfrom'globals';importtseslintfrom'typescript-eslint';exportdefaulttseslint.config({ignores:['**/dist/**','**/build/**','**/coverage/**','**/node_modules/**','eslint.config.mjs',],},eslint.configs.recommended,...tseslint.configs.recommended,eslintConfigPrettier,// 后端 Node / TS{files:['apps/api/**/*.ts','packages/**/*.ts'],extends:[...tseslint.configs.recommendedTypeChecked],languageOptions:{globals:globals.node,parserOptions:{projectService:true,tsconfigRootDir:import.meta.dirname,},},rules:{'@typescript-eslint/no-floating-promises':'warn','@typescript-eslint/no-unsafe-argument':'warn',},},// 前端 TS / TSX{files:['apps/web/**/*.{ts,tsx}'],extends:[...tseslint.configs.recommendedTypeChecked],languageOptions:{globals:globals.browser,parserOptions:{projectService:true,tsconfigRootDir:import.meta.dirname,},},rules:{'@typescript-eslint/no-unused-vars':['warn',{argsIgnorePattern:'^_'}],},},// 构建脚本 .mjs{files:['**/*.{mjs,cjs}'],languageOptions:{globals:globals.node},},);不 lint*.css,CSS 交给 Stylelint。
八、stylelint.config.mjs(只做 CSS 语法/语义)
/** @type {import('stylelint').Config} */exportdefault{extends:['stylelint-config-standard','stylelint-config-prettier',],ignoreFiles:['**/node_modules/**','**/dist/**','**/build/**','**/*.min.css',],rules:{// ── 下面只保留「语义/语法」类规则示例,按团队调整 ──},};stylelint-config-prettier做了什么?
自动关闭Stylelint 里和排版相关的规则,例如:
indentationmax-line-lengthstring-quotesdeclaration-block-trailing-semicolon- 等等
这样 Stylelint不会和 Prettier 抢 CSS 格式。
Stylelint 仍会检查的典型问题(非格式)
| 类型 | 例子 |
|---|---|
| 语法错误 | 写错属性名、非法值 |
| 未知伪类/元素 | 拼错的:hover |
| 重复/冲突 | 重复声明、无效组合 |
| 最佳实践 | 空源、错误@import用法等 |
具体以stylelint-config-standard为准;团队不喜欢的规则在rules里null关掉。
SCSS 项目
exportdefault{extends:['stylelint-config-standard-scss','stylelint-config-prettier',],// ...};九、.stylelintignore(可选)
node_modules dist build coverage *.min.css十、.editorconfig(可选)
root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false与.prettierrc的tabWidth: 2、endOfLine: lf保持一致。
十一、根package.jsonscripts
{"scripts":{"format":"prettier --write .","format:check":"prettier --check .","lint":"eslint . && stylelint \"**/*.{css,scss}\"","lint:fix":"eslint . --fix && stylelint \"**/*.{css,scss}\" --fix","check":"npm run format:check && npm run lint"}}| 命令 | 作用 |
|---|---|
format | Prettier 格式化全仓库(含 CSS) |
format:check | CI 卡未格式化的代码 |
lint | ESLint(TS/JS 质量)+ Stylelint(CSS 语法) |
lint:fix | 各自 auto-fix(CSS fix 不修 Prettier 管的格式) |
十二、保存时执行顺序(心里有数)
1. Prettier formatOnSave → 排版(TS + CSS 都变) 2. ESLint fixAll → TS/JS 质量 3. Stylelint fixAll → CSS 语义可修项(不动 Prettier 已排的版)偶尔 Prettier 和 Stylelint fix 会来回动一下,一般保存两次就稳;CI 用format:check+lint兜底。
十三、冲突防控清单
| ✅ 要做 | ❌ 不要做 |
|---|---|
格式只写.prettierrc | settings.json里写prettier.* |
ESLint 加eslint-config-prettier | ESLint 开indent/quotes/semi |
Stylelint 加stylelint-config-prettier | Stylelint 开indentation/max-line-length |
| CSS 用 Prettier 格式化 | 用 Stylelint 管缩进换行 |
CI 跑prettier --check | 只靠肉眼保证格式 |
十四、目录结构示例
repo/ ├── .prettierrc ├── .prettierignore ├── .editorconfig ├── eslint.config.mjs # JS/TS 质量 ├── stylelint.config.mjs # CSS 语法/语义(不管格式) ├── .stylelintignore ├── .vscode/ │ ├── settings.json │ └── extensions.json ├── package.json ├── apps/ │ ├── api/ # Nest/Koa,无 CSS │ └── web/ # React/Vue,有 CSS └── packages/ └── shared/十五、三工具一句话
- Prettier:全仓库「长得整齐」(含 CSS 排版)
- ESLint:TS/JS「写得对不对」
- Stylelint:CSS「用得对不对」(语法/语义),排版一律不管
若要落到你某个具体仓库(单仓或 imH5 + imAdminUIReact + imAdminNest 三仓共用同一份配置),切 Agent 模式可以说一下仓库结构,我可以按路径改好files匹配规则。