基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
编程提效2026-11-05 17:01

先拦住新增违规,再让 Agent 清理旧账

dev.to · AI#ESLint#技术债#AI编程
Editor brief · 编辑速览

文章介绍用 ESLint 批量抑制记录历史违规,在启用严格规则的同时约束新增代码。随后按目录把旧问题拆成可验证的小任务交给编程 Agent;该机制仅适用于设为 error 的规则。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

一条严格的 ESLint 规则,常常不是没人认可,而是一打开就冒出几百个错误,谁也不想接那个横跨全仓库的 PR。作者给出的办法是:先登记历史欠账,让规则立即约束后续代码,再把旧问题按目录拆给 AI 编程代理处理。

这套流程最值得借鉴的,是如何把一次大迁移变成可验收的小任务。不过,它能保证的是检查机制开始运转;类型是否修对、代理有没有绕过规则,还得靠测试和审查。

先让规则生效,历史错误可以分批还

原文以 @typescript-eslint/no-explicit-any 为例。过去团队可能因为存量 any 太多,直接关闭规则,结果新旧问题一起增长。

ESLint 在 v9.24.0,2025 年 4 月 4 日发布的 bulk suppressions,允许把已有违规记录到文件里。配置中先将规则设为 "error",再执行 npx eslint . --suppress-rule @typescript-eslint/no-explicit-any --fix。

这里必须是 "error","warn" 不会被批量抑制。命令生成项目根目录下的 eslint-suppressions.json,按「文件路径、规则、数量」登记旧问题,然后把它提交进仓库。

--fix 会先修复能自动修复的问题。no-explicit-any 在默认选项下不能自动修复,但配置里的其他规则可能改动文件,因此作者要求从干净的工作区执行,并检查 diff。

多个规则可以重复传入 --suppress-rule;--suppress-all 则记录所有处于 "error" 级别的规则。路径相对于工作目录,采用 POSIX 格式;从 v9.27.0 开始,键会排序,减少无关 diff。如果用 --suppressions-location 改存放位置,后续每次运行都要带上它。

先接纳历史欠账,才有机会立即阻止欠账继续增长。

但这里有个边界:抑制记录按文件和规则计数,不绑定具体行。某文件登记了 4 个 any,后来出现第 5 个,ESLint 无法判断哪个是新增的,会把这项规则的全部违规都报出来。

单向转动的棘轮与逐渐减少的历史错误

CI 仍然执行 npx eslint .。修掉旧问题后,还要运行 npx eslint . --prune-suppressions,清理多余记录;否则 ESLint 默认以退出码 2 报告未使用的抑制项。

v9.28.0 新增的 --pass-on-unpruned-suppressions 可以让这些残留项不影响退出码。作者认为本地可以用,CI 应当关掉,否则账本会逐渐失真。

此外,创建和清理记录只能使用 CLI。Node.js API 到 v10.1.0 才能通过 applySuppressions: true 应用已有记录;编辑器是否停止标红,取决于它的 ESLint 集成有没有启用这个选项。

给代理的任务,应该小到能一次审完

作者没有让代理直接「修复整个仓库」,而是先用 jq 盘点分布。统计单条规则总数时,先设置 RULE=@typescript-eslint/no-explicit-any,再执行 jq --arg r "$RULE" '[.[] | .[$r].count // empty] | add' eslint-suppressions.json。

下面这段按路径前两段汇总,生成从多到少的目录清单:

jq -r --arg r "$RULE" '
  [ to_entries[]
    | select(.value[$r])
    | { dir: (.key | split("/") | .[0:2] | join("/")),
        n: .value[$r].count } ]
  | group_by(.dir)
  | map("\(map(.n) | add)\t\(.[0].dir)")
  | .[]' eslint-suppressions.json | sort -rn

重点看 .[0:2]:如果某个目录仍然过大,可以针对该子树改成 .[0:3],继续拆分。合适的粒度,是代理一次能完成、人一次能审完。

每个目录使用相同任务模板,只替换路径:

Fix every @typescript-eslint/no-explicit-any error
in src/billing. Use real types, or unknown plus a
type guard. Do not add eslint-disable comments and
do not add casts whose only job is to silence the
rule. Do not edit files outside src/billing.
Keep runtime behavior the same; run the tests.
When done, run `npx eslint . --prune-suppressions`,
then `npx eslint .` must pass. Commit the code and
eslint-suppressions.json together.

最关键的是禁止靠 eslint-disable 和纯消音用途的类型断言过关。unknown 配合类型守卫,要求代码先检查值,再使用它,比直接把 any 换成一个断言更有约束。

模板还存在一个小歧义:它禁止修改目录外文件,却要求更新根目录的抑制文件。实际使用时,应明确允许修改 eslint-suppressions.json。

多个代理也不应共用同一个工作目录。原文用 git worktree add -b lint/any-billing ../app-any-billing 和 git worktree add -b lint/any-users ../app-any-users,分别建立分支和目录,避免互相覆盖修改。

作者开发的 Hermes IDE 将这套操作包装成任务入口,可以选择 Claude Code、Codex 或其他代理。.hermes/worktree.toml 用 setup = ["npm ci"] 准备依赖,用 done_when = ["npx eslint ."] 设置完成检查。这里的产品介绍有作者自身立场,但底层方法用普通 Git 同样能做。

验收要看代码,也要看欠账是否真的减少

任务完成后,作者要求同时检查源码 diff 和抑制文件:减少的数量,应当能对应到实际修复。如果处理 src/billing,却删掉了 src/users 的记录,就需要追查原因。

--prune-suppressions 会删除不再匹配违规的记录,以及已删除文件的条目。因此,「账本变小」只是线索,不能单独证明修复正确。

作者还给了一个快速检查:运行 git diff main...HEAD | grep '^+.*eslint-disable',寻找新增的禁用注释。但它只能覆盖这一类绕行方式;代理新增的每个 as SomeType,仍要人工确认有没有相应检查。

Hermes 的 Review Desk 可以按轮次或文件查看改动,行内评论会返回给对应代理。这个界面的实际价值,是把代码和抑制文件放在同一次审查里。

Hermes 按轮次展示源码差异和变更文件

如果多个分支修改抑制文件导致冲突,作者建议在双方都只删除记录的前提下,取其中一份,再对合并后的代码运行 npx eslint . --prune-suppressions。这样可以重新生成符合当前代码状态的账本,随后仍应运行完整 lint 检查。

我的判断

我认可它把「规则是否值得启用」和「旧代码何时修完」分开处理。相比一直关闭规则,它能尽早约束后续开发;相比满仓添加禁用注释,它把迁移欠账集中在一个文件里,也更方便盘点。

但作者没有提供代理修复耗时、成功率或人工对照数据。「代理能更快消化清单」在这篇里属于经验判断,不能直接当作效率结论。

更需要留意的是计数机制的局限。同一个文件里修掉一个旧 any,又新增一个 any,总数不变,检查未必能识别。有人重新执行 --suppress-rule、提交更大的抑制额度,CI 也可能通过。

它限制的是违规数量,不能独立证明每一处类型都变得更可靠。

与允许长期保留的局部禁用注释相比,bulk suppressions 更适合团队已经认可、准备逐步清偿的迁移任务。如果规则本身还有争议,先登记几百条欠账,只是推迟讨论。高欠账文件一旦超额就集中报错,也应提前向团队说明,避免干扰无关 PR。

能拿来做什么

  • 在现有 TypeScript 前端或 Node 项目里,先选一条团队已经认可的严格规则,登记存量问题,再让 CI 阻止数量继续增长。
  • 给 AI 编程代理分配一个可独立审查的目录,明确真实类型、unknown 和类型守卫的使用要求,并把禁止绕过规则写进任务。
  • 审查时把源码、测试结果和 eslint-suppressions.json 放在一起看,重点检查新增断言、禁用注释以及抑制额度增加。
  • 并行处理多个目录时使用独立 worktree;合并后重新清理抑制记录,并运行完整 lint,确认账本与最终代码一致。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
让编程智能体先估算规模再动手
下一篇
Lambda 可直接跑 HTTP 服务,单环境并发达128

资讯速览

dev.to · AI · 2026-11-05 17:01

AI 评分 8.0 / 10

相关标签

#ESLint#技术债#AI编程

继续阅读

  • 提示词实验:五个智能体未胜过单体
  • 让编程智能体先估算规模再动手
  • Lambda 可直接跑 HTTP 服务,单环境并发达128
  • NVIDIA 用企业语义层约束 Agent 数据查询
  • 跨框架 Agent 如何协作:理解 A2A 与 MCP