Skill 管不住代码风格时:把项目约定写成 ESLint 护栏
Skill 很适合写项目约定:目录怎么分、组件怎么拆、哪些写法要避开、改代码前要看哪些文件。问题是,Skill 只是提示,它不能真的拦住 Agent 下一次继续写偏。
更稳的一层,是把已经反复出现、可以被静态判断的项目约定做成 ESLint 规则;少数跨文件、资源或构建产物相关的问题,则交给脚本检查。这样 Agent 写偏以后,编辑器能直接打波浪线,pnpm lint 或 CI 也能把问题暴露出来。对人也一样,review 不需要反复解释同一句口径。
这批规则后来已经整理成 @sheng/eslint-plugin。规则分组、在线示例、接入方式和选项边界统一放在 GitHub Pages 文档站;想查某条规则会报什么、怎么配置、适不适合当前项目,直接看规则列表。
约定应该进入 Lint,还是继续留在文档、review 或专项脚本里,取决于它能否被稳定判断,以及判断需要读取哪些信息。
规则不是为了统一审美
项目约定型规则和 Prettier 的边界不同,也不能只来自个人口味。一条约定值得变成 ESLint,通常要满足一个条件:它反复制造了可预期的维护成本。
适合规则化的问题大致有三类:
- 会破坏工具链。代码看起来能运行,但会让 IDE、静态扫描、翻译平台、类型检查或构建链路失去真实信息。
- 会把反馈推迟到运行时。源码阶段已经能判断风险,却要等 dev server、浏览器控制台、构建日志或线上页面才暴露。
- 会增加重复 review 成本。团队已经形成稳定约定,每次 Agent 或开发者写偏时,review 都在重复解释同一套口径。
这些规则让问题更早、更靠近代码现场出现。能在编辑器里出现波浪线的问题,不应该长期留到 PR review 里靠人提醒。
Skill、Lint 和脚本各管一层
Skill 和 AGENTS.md 适合写意图:为什么这么拆目录、某类组件应该先看哪些文件、哪些场景要避开某种写法。它们能帮助 Agent 在动手前建立上下文,也能让人快速理解项目偏好。
ESLint 适合检查那些可以从 AST、作用域、文件路径或少量项目配置里稳定判断的问题。比如某个调用参数必须是静态值,某类 import 的目标文件必须真实存在,某种表达式结构已经稳定被团队认定为噪音。开发者可以直接根据代码旁边的提示判断问题,不必先读完整套方法论。
脚本检查适合更重的边界:需要读文件系统、解析资源文件、检查构建产物,或者跨 Vue、CSS、SVG、JSON 多种文件一起判断。把这类问题硬塞进 ESLint,往往会让规则又慢又难配置。脚本可以跑在 pnpm check、CI 或发布前流程里,作为 ESLint 的补充。
review 仍然保留最终判断。Lint 能指出结构风险,但不能替开发者理解全部业务上下文。尤其是项目风格型规则,命中后应该问「这里是不是确实破坏了约定」,而不是机械追求零提示。

从 warn 开始
项目约定型规则第一版大多适合用 warn。原因很简单:旧代码里可能已经有历史例外,规则实现也需要一段时间观察误报。先让危险结构变得可见,比一上来让 CI 拦死所有历史代码更稳。
确认误报很少、例外已经能通过 options 或局部注释表达后,再考虑把部分规则升成 error。适合升成 error 的通常是确定会坏的问题:运行时值拿不到、资源文件不存在、编译器宏不会被识别、生产构建会失败。这类问题继续用 warn,错误就可能要等到运行或构建时才真正阻止流程。
严重级别也可以按场景拆开。开发目录先 warn,新代码目录先 error;迁移期只扫某个 feature,稳定后再扩大范围。规则本身要配置化,把函数名、alias、忽略路径和历史例外交给项目配置,不要写死在规则源码里。
规则文档放在规则旁边
最早写这篇文章时,我把很多具体规则、示例和源码包都放在同一篇里。这样短期很方便,长期会有两个问题:文章越来越像规则手册;规则一改,博客就容易过期。
现在更合适的分工是:
- 博客讲方法论:为什么 Skill 管不住代码风格,什么时候需要把约定做成护栏。
- 文档站讲规则:每条规则为什么需要、会提示什么、推荐写法是什么、有哪些配置和边界。
- 源码仓库承载实现:规则源码、测试、在线 demo、发布版本和维护入口都跟着
@sheng/eslint-plugin走。
@sheng/eslint-plugin 的使用指南里保留了接入方式和 parser 配置;规则列表按场景分组,规则页里有可编辑示例和诊断回显。以后如果某条规则需要展开背景,优先单独写一篇对应规则的文章,再从规则页和方法论文章互相链接。
当前规则 demo 和源码由文档站及插件仓库提供,文章里不再内嵌;早期源码包仍作为历史快照留在站点资源里。接入新项目时,应该优先使用当前维护的 npm 包和文档站。
什么时候不要写规则
不是每条 review 意见都适合变成 ESLint。
如果一个判断依赖业务语义、需求背景或设计稿取舍,规则很容易变成噪音。比如某个组件是否应该拆分、某段逻辑是否该抽 composable、某个命名是不是足够表达业务,这些问题可以写进 Skill、架构文档或 review checklist,不一定要让 AST 去猜。
规则如果需要维护大量项目私有例外,也要先停一下。例外比正例还多,通常说明约定本身还没稳定,或者规则边界太贪心;先收窄到最确定的场景,比一开始追求覆盖所有坏味道更可靠。
如果问题只发生过一次,也不急着写规则。可以先把 review 口径写进 Skill,观察 Agent 后面会不会重复犯。重复出现、能稳定描述、能写出最小错误示例,再沉淀成 Lint 护栏。
规则只管稳定坏味道
- Skill 负责解释项目约定,ESLint 负责把可静态判断的偏离变成编辑器和 CI 信号。
- 值得规则化的问题,通常会破坏工具链、推迟反馈,或者反复消耗 review 成本。
- 项目约定型规则先用
warn更稳,等误报和例外都梳理清楚,再把确定会坏的问题升成error。 - 规则文档应该跟着规则源码走。博客保留方法论,具体规则说明、示例、配置和在线 demo 放到文档站。
- 不要把所有偏好都写成规则。业务判断、还不稳定的约定和大量例外,先留在 Skill、文档或 review 里。