news 2026/6/6 10:28:58

代码规范:ESLint + Prettier 配置实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码规范:ESLint + Prettier 配置实战

本文面向:正在搭建代码规范工具链、想在 TypeScript + React monorepo 中落地 Lint 的开发者。
预计阅读时间:11 分钟
最终效果:掌握 ESLint Flat Config、Biome 与 ESLint 的分工、Prettier 冲突处理,以及 pre-commit 与 CI 双层门禁的搭建方法。

为什么需要 Lint

你一定遇到过这些情况:提交代码后 CI 报了一堆红,排查半天发现是一个未使用的变量;或者团队成员的代码风格各异,有人用单引号有人用双引号,review 的时候光在格式上浪费时间。

Lint 工具解决的就是这类问题:

  • 自动发现 bug:未使用的变量、错误的依赖数组、缺失的 key 属性
  • 统一代码风格:缩进、引号、分号——不需要在 code review 里争论
  • 提升可维护性:强制最佳实践,减少技术债积累
  • CI 门禁:在合并前拦截问题,而不是部署后才发现

ChatCrystal 是一个包含三个 workspace(shared、server、client)的 monorepo,代码检查需要覆盖所有子项目。项目的npm run lint命令会同时运行 Biome(全仓库通用检查)和 ESLint(客户端 React/TypeScript 专项检查),两者互补。

ESLint 配置:Flat Config 时代

从 ESLint v9 开始,官方推荐使用Flat Config(扁平配置),也就是eslint.config.js文件,取代了传统的.eslintrc系列格式。

ChatCrystal 的客户端 ESLint 配置(client/eslint.config.js):

importjsfrom'@eslint/js'importglobalsfrom'globals'importreactHooksfrom'eslint-plugin-react-hooks'importreactRefreshfrom'eslint-plugin-react-refresh'importtseslintfrom'typescript-eslint'import{defineConfig,globalIgnores}from'eslint/config'exportdefaultdefineConfig([globalIgnores(['dist']),{files:['**/*.{ts,tsx}'],extends:[js.configs.recommended,tseslint.configs.recommended,reactHooks.configs.flat.recommended,reactRefresh.configs.vite,],languageOptions:{ecmaVersion:2020,globals:globals.browser,},rules:{'react-hooks/set-state-in-effect':'off',},},])

逐行拆解:

globalIgnores(['dist'])— 全局忽略构建产物目录。Flat Config 不再使用.eslintignore文件,忽略规则直接写在配置里。

files: ['**/*.{ts,tsx}']— 只对 TypeScript 文件生效。纯 JS 文件不参与检查,避免对第三方代码或配置文件误报。

extends配置组

  • js.configs.recommended— ESLint 自身的推荐规则,涵盖常见的 JS 错误模式
  • tseslint.configs.recommended— TypeScript 专属规则,包括类型相关的检查
  • reactHooks.configs.flat.recommended— React Hooks 的规则,防止useEffect依赖遗漏等问题
  • reactRefresh.configs.vite— Vite HMR 环境下的 React 组件导出规范

languageOptions.globals— 声明windowdocument等浏览器全局变量,避免 ESLint 报 “xxx is not defined”。

rules覆盖react-hooks/set-state-in-effect设为off,这是项目中特定场景下的权衡,不是每个项目都需要。

TypeScript ESLint 集成

TypeScript 是 ChatCrystal 的核心语言,typescript-eslint包提供了 TypeScript 语法感知的 lint 能力。

安装依赖:

npminstall-Deslint typescript-eslint @eslint/js globals

typescript-eslint的作用不仅仅是让 ESLint 能解析.ts文件的语法(比如类型注解、接口声明),更重要的是提供了一系列 TypeScript 特有的规则:

  • 禁止any类型的滥用
  • 检查未使用的导入和变量
  • 强制枚举成员使用 PascalCase
  • 检测@ts-ignore的使用

这些规则在纯 JavaScript 的 ESLint 中是无法实现的,因为它们需要理解 TypeScript 的类型系统。

Monorepo 中的 Lint 策略

ChatCrystal 采用双层 lint架构:

{"scripts":{"lint":"biome check . --diagnostic-level=error && npm run lint -w client","lint:fix":"biome check --fix . && npm run lint -w client -- --fix"}}

第一层Biome负责全仓库检查(server、shared、client、electron、scripts),第二层ESLint专门负责客户端的 React + TypeScript 规则。

这种设计的原因是:

  1. Biome 快:用 Rust 编写,对整个 monorepo 的 lint 耗时极短,适合做通用检查
  2. ESLint 生态丰富:React Hooks、React Refresh 等插件是 Biome 目前不完全覆盖的
  3. 职责分离:通用规则和框架专属规则各司其职

运行方式:

# 检查问题(不修改文件)npmrun lint# 自动修复可修复的问题npmrun lint:fix

客户端 workspace 内部也有独立的 lint 脚本:

# 仅对 client 目录运行 ESLintnpmrun lint-wclient# 自动修复npmrun lint-wclient ----fix

Prettier:格式化的分工

在 ChatCrystal 中,Biome 只负责全仓库 lint——biome.jsonformatterassist都是关闭的("enabled": false),只开了linter。也就是说项目并没有启用独立的格式化工具,而是靠 lint 规则加编辑器默认格式化来保持风格一致。下面这套 Prettier 配置是面向"如果你的项目要引入专门的格式化工具"的通用方案,不代表 ChatCrystal 的实际配置。

但如果你的项目选择 Prettier 做格式化,关键是要解决 ESLint 和 Prettier 的规则冲突。ESLint 的部分规则(比如no-mixed-spaces-and-tabs)和 Prettier 的格式化行为可能互相矛盾。

解决方案是安装eslint-config-prettier,它会关闭所有和 Prettier 冲突的 ESLint 规则:

npminstall-Dprettier eslint-config-prettier

在配置中把 Prettier 放在最后:

// 传统 .eslintrc 格式{"extends":["eslint:recommended","plugin:@typescript-eslint/recommended","prettier"// 放在最后,关闭冲突规则]}

Flat Config 中的写法:

importprettierConfigfrom'eslint-config-prettier'exportdefault[js.configs.recommended,tseslint.configs.recommended,prettierConfig,// 放在最后]

Prettier 本身的配置文件.prettierrc

{"semi":false,"singleQuote":true,"trailingComma":"all","printWidth":100,"tabWidth":2}

核心原则:ESLint 管代码质量,Prettier 管代码格式,两者不重叠

编辑器集成

代码规范工具的最大价值在于开发时即时反馈,而不是提交时才发现问题。

VS Code 配置.vscode/settings.json):

{"editor.formatOnSave":true,"editor.defaultFormatter":"esbenp.prettier-vscode","editor.codeActionsOnSave":{"source.fixAll.eslint":"explicit"},"eslint.validate":["typescript","typescriptreact"]}

配置后,保存文件时会自动格式化 + 自动修复 ESLint 问题,开发体验流畅。

Cursor / 其他 VS Code 分支的配置方式相同,因为它们共享同一套 extension API。

Pre-commit Hooks:提交前的最后一道防线

编辑器集成依赖开发者主动配置,而 pre-commit hooks 是强制执行的机制——不管用什么编辑器,提交代码前必须通过检查。

使用husky+lint-staged的经典方案:

npminstall-Dhusky lint-staged npx husky init

package.json中配置 lint-staged:

{"lint-staged":{"*.{ts,tsx}":["eslint --fix","biome check --fix"],"*.{json,css,md}":["biome check --fix"]}}

.husky/pre-commit文件:

npx lint-staged

工作流程:git commit触发 husky → husky 运行 lint-staged → lint-staged 只对暂存区的文件执行检查和修复 → 检查通过才允许提交。

lint-staged 的优势是只检查本次修改的文件,而不是整个项目,所以速度很快,不会影响日常开发节奏。

CI 中的 Lint 检查

Pre-commit hooks 是本地防线,CI 是远程门禁。两者缺一不可——开发者可以绕过本地 hooks(git commit --no-verify),但无法绕过 CI。

在 GitHub Actions 中添加 lint 步骤:

name:CIon:[push,pull_request]jobs:lint:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:actions/setup-node@v4with:node-version:20cache:npm-run:npm ci-run:npm run lint

npm run lint命令会依次运行 Biome 和 ESLint,任何一步失败都会让 CI 变红,阻止 PR 合并。

建议在 CI 中只检查不修复(用npm run lint而非npm run lint:fix),因为 CI 的职责是发现问题,而不是悄悄改代码。

实用技巧

1. 忽略特定规则

有时某条规则在特定场景下不合理,可以用行内注释临时关闭:

// eslint-disable-next-line @typescript-eslint/no-explicit-anyconstdata:any=awaitfetchLegacyApi()

但要注意:这只是临时方案。如果同一规则被大量 disable,说明这条规则可能不适合你的项目,应该在配置文件中统一调整。

2. 查看所有生效的规则

npx eslint --print-config src/App.tsx

这会输出对指定文件生效的完整规则列表,调试配置问题时非常有用。

3. 渐进式接入

在一个没有 lint 的项目中引入 ESLint 时,不要一开始就开启所有推荐规则。可以先用warn级别代替error,逐步收紧:

rules:{'@typescript-eslint/no-explicit-any':'warn','@typescript-eslint/no-unused-vars':'warn',}

等团队适应后再升级为error,避免一次性冒出上百个报错。

小结

工具职责ChatCrystal 中的角色
ESLint代码质量检查客户端 React/TypeScript 专项检查
BiomeLint(formatter 已关闭)全仓库通用 lint(替代部分 ESLint)
Prettier代码格式化未使用;本仓库未启用独立格式化工具
husky + lint-stagedPre-commit hook本地提交门禁
GitHub ActionsCI 检查远程合并门禁

ChatCrystal 的实践表明,代码规范不需要追求工具数量,关键是覆盖完整、分工明确、执行到位。用 Biome 做通用检查,用 ESLint 做框架专属检查,配合 pre-commit hooks 和 CI 形成完整的质量保障链路。

下一步

  • 在自己的项目中运行npx eslint --init,体验 Flat Config 的交互式初始化
  • 对比 Biome 和 ESLint + Prettier 的性能差异,选择适合团队的方案
  • 配置 husky + lint-staged,让代码规范成为团队习惯而非文档条款
  • 阅读 ESLint 官方文档 了解完整的规则配置

ChatCrystal 项目代码开源在 GitHub,欢迎查阅完整的 lint 配置实现。


项目地址:github.com/ZengLiangYi/ChatCrystal

如有疑问欢迎在 GitHub Issues 或私信交流,很乐意解答。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 10:26:22

效率提升:告别手动清理!用快马AI生成dxcache自动化管理脚本

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个用于提升开发效率的自动化缓存清理脚本。该脚本应能作为命令行工具或计划任务运行。核心功能包括:首先,通过配置文件或命令行参数定义需要监控的…

作者头像 李华
网站建设 2026/6/6 10:26:01

AI赋能安全,利用快马多模型生成智能流量异常检测程序原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个AI辅助的简单网络流量异常检测程序原型。程序需要实现以下功能:首先,提供一个接口(如上传文件或输入示例数据)来接收一段…

作者头像 李华
网站建设 2026/6/6 10:21:57

利用快马平台aigc能力,十分钟搭建智能博客大纲生成器原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请使用快马平台生成一个基于aigc技术的快速原型应用。该应用是一个智能博客大纲生成器,核心功能包括:用户输入一个博客主题关键词,系统调用aigc…

作者头像 李华
网站建设 2026/6/6 10:17:44

新手福音:无需精通visio,用快马AI生成你的第一个网页流程图应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 我是一个编程新手,想学习如何创建网页版的流程图工具,请帮我生成一个入门级的流程图绘制项目代码,要求实现以下简单功能:创建一个网…

作者头像 李华