Lint 与质量门禁
构建保证「能打出包」;质量门禁保证 明显的错在进主分支前失败。类型检查见 配置与工程实践;安装器与 CI 安装见 包管理工具。
门禁要短、可复现、与编辑器同一套规则。规则比人多时,没人会修。
解决什么问题
| 痛点 | 门禁怎么帮 |
|---|---|
| 有人用了已禁止的 API | ESLint 规则 / no-restricted-imports |
| 格式战争 | Prettier(或 ESLint stylistic)统一,停止讨论空格 |
| 编辑器绿、CI 红 | 版本和配置没进仓库,或只装了编辑器插件 |
| 类型错误进主支 | CI 跑 tsc --noEmit,不只靠 IDE |
一句话:编辑器是提示;CI 才是门。本地 hook 用来少等 CI。
分工
| 工具 | 管什么 | 不管什么 |
|---|---|---|
| Prettier | 格式(换行、引号、宽) | 对错 |
| ESLint | 对错与最佳实践、部分格式 | 完整类型(交给 tsc) |
tsc --noEmit | 类型 | 代码风格 |
| Stylelint | CSS/样式 | JS |
ESLint 与 Prettier 重叠时:让 Prettier 管格式,ESLint 关掉冲突规则(eslint-config-prettier)。不要两套都格式化还配得不一致。
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"typecheck": "tsc --noEmit"
}
}
先认现场
| 标志 | 含义 |
|---|---|
eslint.config.js | 新扁平配置(ESLint 9+) |
.eslintrc.* | 旧格式,存量很多 |
.prettierrc* | 格式配置 |
.husky/ / lint-staged | 提交前只扫暂存文件 |
| 只有编辑器插件、仓库无配置 | 门禁不存在,换台电脑就失效 |
跟仓库现有 config 走;新项目再选扁平配置。typescript-eslint 让 ESLint 理解 TS 语法;类型感知规则更慢,可放 CI,本地用较快子集。
Git hook 与 CI
本地: lint-staged(只查本次改动) → 可选 typecheck
CI : install frozen → lint → typecheck → build → 测试(若有)
lint-staged 例:暂存的 *.{ts,tsx} 跑 ESLint + Prettier。不要在 hook 里跑全仓库 tsc 除非仓很小——人会 --no-verify 绕过。
CI 必须跑全量。钩子被绕过时,CI 是最后一道。
最小 GitHub Actions 直觉(命令以仓库为准):
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm build
规则怎么选
| 建议 | 原因 |
|---|---|
先开社区 preset(如 eslint:recommended + 框架 preset) | 少发明 |
no-restricted-imports 禁深挖内部路径 | 比 code review 稳 |
错误用 error,风格能 autofix 的交给 Prettier | 减少噪音 |
少用 eslint-disable;禁用要写原因 | 否则等于没门禁 |
发现团队全是 disable 注释,说明规则不适合现状,改规则或改代码,不要堆忽略。
要点
- 格式 / 对错 / 类型三套工具,职责分开
- 配置进 Git,CI 跑与本地同一命令
- hook 求快(staged);CI 求全
--no-verify存在,所以 CI 不能省- 规则要能 autofix 或有明确错误信息,否则没人遵守
面试速记
- ESLint 和 Prettier 区别? 一个偏对错与模式,一个偏格式;冲突时格式交给 Prettier。
- 为什么还要
tsc? Lint 替代不了完整类型系统。 - husky 干什么? 在 commit/push 时跑脚本;真正拦合并的是 CI。
- lint-staged 为什么快? 只处理暂存文件,而不是全仓库。
- 编辑器绿、CI 红常见原因? 插件版本/配置与 CI 不一致,或本地没装依赖只靠编辑器内置。