尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

anti-slop 规则集实战:用 Oxlint 把代码质量变成工程门禁

anti-slop 规则集实战:用 Oxlint 把代码质量变成工程门禁 anti-slop 这个名字第一次看到的时候很容易以为是一组“看代码不顺眼就想管一管”的任性规则。实际用过之后我更愿意把它理解成一套有明确价值取向的 Oxlint 规则集合目标不是让代码“能跑”而是让代码不脏、不慌、不至于在三个月后没人敢改。如果你正在负责前端工程的 lint 配置或者刚从 ESLint 迁移到 Oxlint又或者团队里有大量 AI 生成代码需要收口那么 anti-slop 这套思路值得你先搞明白。它真正最值钱的地方不在规则数量而在于把“规范”从可选项变成了门禁。从标题里的两个关键词来看anti-slop 描述的是约束目标Oxlint 描述的是执行载体。它想解决的是很多工程团队都会遇到的真实问题代码没有明显报错但处处都是隐患。今天这篇就按实际落地顺序拆一遍先讲概念再讲环境然后讲规则怎么配、批量任务和 CI 怎么接最后把常见的坑和排查顺序一并说清楚。1. 先搞清楚 anti-slop 管的是哪一类问题1.1 SLOP 并不是脏话它是代码里常见的偷懒模式SLOP 这个说法在程序员圈子里流行起来和 AI 生成代码变得普遍有很大关系。它并不是指某种具体技术而是描述一类“看起来能用、细看全是毛病”的代码。典型的 SLOP 包括先把逻辑堆上去再说的垃圾注释、到处留着的调试日志、为绕过类型报错随手写的 any、空 catch 块、函数越来越长、分支逻辑不断叠加、复制粘贴后只改了一半的重复代码。这些代码不会立刻让项目崩掉但会持续消耗维护者的精力。你以为是业务逻辑复杂结果回头一看很多复杂度根本不是业务要求的而是写代码的人偷懒留下的。anti-slop 的立场很直接这些偷懒模式不应该只靠 code review 时靠眼睛发现应该用规则在提交之前就挡住。所以 anti-slop 的前提是你已经承认规则是有必要的。如果你觉得 lint 只是在制造麻烦那这套思路你会越看越别扭。它不是为了让你开心的工具而是为了减少未来踩坑概率的约束。1.2 anti-slop 的价值不在规则数量在“有观点”Oxlint 本身已经内置了很多规则ESLint 生态里也有几千条规则。anti-slop 如果只是把规则数量堆上去意义不大。它真正值得注意的是“有观点”三个字。普通 lint 配置往往分两类。一类是只开官方推荐追求兼容性规则能跑就行另一类是规则开放得非常多每个文件打开都是满屏警告团队成员很快产生“lint 疲劳”。anti-slop 的思路不太一样它明确告诉你哪些代码模式是不被接受的并且默认用 error 级别去拦。它不试图讨好所有人也不追求“一条规则都不误报”。我理解这种“有观点”体现在几个判断上代码不是只要正确就行还要不能被误读。代码不是只要简洁就行还要能稳定维护。代码不是只要通过类型检查就行还要经得起三个月后陌生人阅读。规则不是用来提建议的是用来做门禁的。一旦你接受这些判断再去看 anti-slop 规则集就会发现它的每一项都不是随机选的而是围绕“减少维护成本”这个目标。1.3 为什么选用 Oxlint 作为这套规则的落点既然要搞一套严格规则为什么不用大家更熟悉的 ESLint原因可以拆成几点。第一是性能。Oxlint 基于 Rust 生态的 Oxc 工具链实现核心卖点就是快。对于大型前端仓库全量 lint 的时间如果从几十秒降到几秒开发体验会完全不一样。严格规则可能会带来很多新警告如果工具本身跑得慢开发者更不愿意在本地跑规则就变成了摆设。第二是配置简单。Oxlint 的定位是“开箱即用”默认就会启用一些高价值规则。它不需要像 ESLint 那样先装解析器、插件、共享配置再处理各种版本冲突。对于刚从零开始建仓库的团队这个优势很明显。第三是它和 ESLint 的关系不是替代而是互补。Oxlint 支持大量与 ESLint 兼容的规则语义这让团队在迁移时不用把配置文件推倒重来。你可以先用 Oxlint 做快速门禁再把更细的检查留给 ESLint 或者 TypeScript 类型检查。当然并不是说 Oxlint 适合所有项目。规则兼容性、插件生态、团队习惯这些因素仍然要评估。但如果你想做一套严格且能跑进 CI 的规则Oxlint 是个很合适的切入点。2. 落地之前先把环境和配置准备好2.1 安装和前置条件能跑通是第一步无论你用的是 npm、pnpm 还是 yarn安装 Oxlint 都不复杂。最常见的方式是在项目中安装局部依赖npm install -D oxlint然后在 package.json 里加一个脚本{ scripts: { lint: oxlint } }如果你只是想临时试一下不想改 package.json也可以用 npxnpx oxlint src我一般会先跑一个具体的输入目录比如src或lib而不是直接对整个项目根目录跑。原因很简单项目根目录里经常有配置文件、构建产物、第三方代码这些目录会被忽略还好一旦没有被正确忽略输出里全是不该看的警告反而浪费时间。网络环境不需要额外担心只要你的包管理器源正常就行。Node 版本建议用当前团队推荐的长期维护版。这里给不了绝对版本号因为不同版本的 Oxlint 对 Node 版本要求会有变化落地时以你安装到的版本说明为准。如果你已经装了 Rust 工具链想直接从源码跑也可以但通常情况下没必要。用 npm 包是最省事的方式。2.2 配置文件放在哪里基本字段怎么理解Oxlint 的配置文件可以使用 JSON 格式。是不是标准名为.oxlintrc.json要看当前版本但整个配置结构是按规则集加参数组织的。一个最基础的示例长这样{ rules: { eqeqeq: error, no-var: error, no-empty: error } }这只是一个演示别直接当成 anti-slop 的标准配置。更关键的是理解三个概念第一个是规则级别。off表示关闭warn表示警告error表示报错。anti-slop 的核心做法是让真正重要的规则保持error否则无法形成门禁。警告往往会被忽略一屏警告里混入一条真错误人也会麻木。第二个是忽略路径。配置文件里一定要有忽略规则否则node_modules、dist、coverage这些目录会混进输出。你可以显式配置也可以依赖默认行为但落地时建议检查一遍。第三个是环境。不同项目可能有浏览器环境、Node 环境、测试环境。规则集和全局变量定义要和这些环境匹配否则会误报console、window、process之类标识符。2.3 第一次运行先看三样东西配置好之后不要急着把规则加满。第一次运行 Oxlint我建议只做三件事。第一确认命令能正常执行没有启动级报错。比如配置语法错误、Node 版本不兼容、模块找不到。第二看扫描范围是否符合预期。你可以故意在一个文件里写一句var x 1如果没被报出来说明文件可能被忽略了或者规则没有开起来。第三看输出是否容易阅读。默认输出会列出文件路径、规则名和错误位置。如果输出混入了大量无关文件先改忽略配置而不是加更多规则。这一步的关键是把工具本身的链路打通。工具跑不起来就谈规则等于还没学会走路就开始跑。2.4 编辑器接入能提升动力命令行 lint 适合 CI 和批量检查但开发者日常应该尽量在编辑器里就看到问题。Oxlint 生态里通常有对应的编辑器插件。如果你用的编辑器支持 LSP可以按官方文档接入。但这里要给一句提醒编辑器报错和命令行 lint 不能完全画等号。编辑器可能使用缓存命令行每次都是真实运行。我见过不少案例开发者在编辑器里看不到任何问题提交到 CI 却开始报错。遇到这种情况不要怀疑规则有 bug先跑一遍命令行把两边的版本和配置对比一下。3. 规则怎么配才算“Opinionated”3.1 优先级应该再清晰一点Correctness 首先要管住anti-slop 不是把风格类规则放在最前面。代码风格当然重要但风格问题不影响运行真正影响维护安全的是“正确性”和“可疑模式”。我建议按下面这个顺序配置正确性类宽松相等、空块、恒定条件、未使用变量、重复逻辑。可疑类可能出现空值但不处理、类型断言过于随意、无限循环风险。性能类不必要的计算、同步阻塞、重复调用高开销函数。风格类变量命名、函数长度、注释风格。正确性类规则优先开成 error。一个项目如果连未使用变量都允许存在后面再加别的严格规则团队会觉得 lint 根本没有原则。除了没有原则还有一个现实问题未使用变量往往是重构没做干净的信号留着它就是留着隐患。3.2 典型 slop 模式以及 anti-slop 会怎么处理下面这些模式是 anti-slop 思路里很容易出现的高频对象。这里不写死规则名因为不同版本的 Oxlint 规则名和默认级别会有差异但核心判断可以看这张表。典型 SLOP 模式代码里常见的样子anti-slop 倾向宽松相等if (res null)强制和!空 catchcatch (e) {}至少要注释原因或记录日志未使用变量参数、导入、局部变量残留直接报错恒真恒假条件while (true)且没有退出条件提示条件可能写错调试日志console.log 随手打不清理或允许统一日志入口禁止散装输出复读注释注释把代码翻译成中文注释应该解释为什么无用抽象一个函数只包一行代码名字还很抽象提示过度设计隐性类型转换字符串直接加减强制显式处理类型这些模式放在一起你会发现一个共性它们都不是“语法错误”而是“可读性债务”。anti-slop 的核心态度就是债务不该由后来人默默承担。3.3 关于 AI 生成代码特殊在哪里现在很多编辑器都集成了 AI 辅助能力像 CodeBuddy 这类工具在生成 lint 配置或补全代码时往往会按“基线可用”的标准输出距离 anti-slop 这种严格门禁还差得很远。AI 生成代码有一个典型特点局部正确整体不自觉。什么意思AI 补全一个函数时它能保证语法正确也能保证大概思路对但它不会考虑你项目里已经存在的命名风格、抽象层次、错误处理约定。它很容易生成没用的 if 判断。重复出现的字段判断。为了泛化而泛化的类型参数。和上下文逻辑重复的注释。复制过来的相似函数只改动了一半。这些内容恰好是传统 lint 规则不太关注、anti-slop 风格规则很想收口的部分。所以如果你的团队大量使用 AI 编程辅助你不能只依赖默认 lint必须有一套更严格的规则集来约束产线代码。当然规则解决不了所有 AI 问题。Code Review 仍然要做。但规则的作用是先把明显不合格的代码挡在外面让 Review 的精力集中在真正需要判断的地方。3.4 自定义规则要克制Oxlint 的扩展性不如 ESLint 生态那么自由但这不一定是坏事。很多人看到规则不够用第一反应是立刻写自定义插件。我的建议是先把现成规则用明白再评估自定义。大部分项目里真正该拦的问题已经有现成规则了只是团队没有开起来。如果确实需要自定义注意两点规则必须服务于具体问题不要为了“我们团队很严格”而加。规则必须能被明确解释说不清楚维护价值的规则很快会被绕过或关掉。4. 从单文件到全仓再到 CI 门禁4.1 先跑单文件再跑整个仓库我一直建议按“单文件 - 单目录 - 全仓库”的顺序推进。原因很简单lint 规则具有连锁效应。你开一条规则后可能一个文件只报 3 处但这个模式在 200 个文件里都有全量跑出来的数字会让人瞬间失去信心。第一次跑全仓之前先在src下选一个小项目把它当成试点。跑完先不看报错总数先看报错集中在哪个规则上。哪些规则是历史遗留哪些规则是最近新增代码引入的心里要有数。如果历史代码大量违规不要一次性把所有规则都设成 error。把规则设好但一部分先保持 warn然后看统计结果。等团队逐步清理完了再把 warn 升成 error。这个过程不是认输是渐进式改进。4.2 批量修复时要控制风险Oxlint 支持自动修复能力但自动修复不是万能药。有些规则可以安全修复比如把var改成let或const有些规则自动修复可能会改变语义比如调整表达式结构、改动类型断言。我的经验是批量修复前先备份提交一次然后用--fix之类的参数跑跑完必须看 diff。哪怕你确定这条规则很安全也要看。因为当文件数量很多时diff 里的异常容易被淹没。需要特别小心的是生成代码不要批量修比如接口类型定义、配置常量改动后可能影响运行。测试代码不要和源码一套标准直接修测试里的宽松断言有时是为了简化输入。模板文件不要无脑修字符串模板里的缩进和空格改动可能改变渲染结果。批量修复不是一次性的清理完这轮下一轮应该越来越少。如果每次 merge 都会新增成批旧规则问题说明 lint 没有真正进入开发流程。4.3 把 Oxlint 接进 CI让它成为门禁本地执行容易偷懒CI 里跑 lint 才能保证每个人提交代码时都被检查。CI 集成的思路其实不复杂安装依赖之后执行oxlint如果规则是 error命令会以非零状态退出流水线就会失败。还可以考虑拆成两步一步只做 lint另一步做类型检查或单元测试。lint 跑得快先失败先反馈不用等所有检查都跑完才发现问题。推荐在 push 和 pull request 时都触发。push 触发能尽早发现pull request 触发能作为合并的前置条件。注意如果仓库本身就带历史警告CI 会因为老问题一直失败团队很容易养成“红着也不管”的习惯。所以接 CI 之前尽量先清理一轮旧问题或者把历史问题通过配置豁免只对新代码保持严格。4.4 输出格式和验收标准运行结果怎么算通过不是“没有红色报错”而是命令退出码为 0并且没有被忽略文件的误导。我建议建立三个明确标准单流程必须跑通从安装、读取配置、扫描目录到输出结果全程无启动异常。严格规则必须拦截故意写入一条应能稳定报错。全仓数量可控全量报错数量应该小于一个阈值并且趋势是下降的。如果你们团队已经有可观测性体系还可以把 lint 告警数作为指标上报。每个版本发布时看一眼告警数量比只看“能不能编译过”更能反映代码健康度。5. 常见报错和排查链路5.1 命令没跑通先看版本和路径如果执行oxlint直接报command not found百分之八十是局部安装没生效或者没有通过 npx 调用。检查npx oxlint --version如果 npx 能跑而脚本里不能多半是 package.json 脚本的 PATH 问题。如果是配置解析失败错误信息里通常会指出第几行第几个字段格式问题最好排查。版本问题也很常见。有些规则在旧版本里不存在你按文档配置了新规则旧版本不识别可能直接报错或被忽略。升级前先看 changelog至少确认规则名有没有变化。5.2 规则没生效先怀疑 ignore 和被覆盖“我明明配置了为什么没有任何反应”这句话我听到过太多次。这时候不要怀疑工具坏了按下面顺序排查。第一检查文件是否真的被扫描。如果文件在dist、build、vendor这类默认忽略目录里它压根不会触发任何规则。第二检查配置是否确实指向了这个文件。如果你在子目录里运行命令配置的加载规则可能和你以为的不一样。建议始终在项目根目录运行。第三检查规则名是否被拼写错误或者当前版本不支持该名称。第四检查同一规则是否在多个层级出现。比如项目根级配置和目录级配置都设置了该规则后加载的配置可能覆盖了前面的。第五检查规则级别确实为error而不是off或warn。warn 在很多时候也会输出但如果你只看退出码可能感觉“规则没生效”。5.3 和 ESLint、Prettier、Biome 一起用怎么处理冲突现实中很多仓库不是只用一个工具。ESLint 管复杂规则Prettier 管格式Oxlint 管快速门禁Biome 可能还承担一部分处理。工具多了必然会有重叠。处理原则是职责边界要清楚。格式类问题统一交给 Prettier不要在 Oxlint 里开一堆缩进、引号、分号规则否则两边标准不一致只会互相打架。正确性和可疑模式类规则Oxlint 和 ESLint 可以同时开但同一规则不要两边都设成 error。你可以让 Oxlint 跑第一遍ESLint 跑第二遍或者反过来。如果两个工具对同一模式给出相反建议优先以项目里已经稳定运行的方案为准不要为了“用上更严格规则”而把现有风格推翻。还有一个更常见的坑Oxlint 配置好了但团队还在旧 ESLint 配置里加了同样的规则两边都不一致。建议把所有 lint 配置放在同一套文档里统一说明减少认知负担。5.4 满屏误报时先别关规则误报是最容易导致团队弃用 lint 的原因。但直接关规则往往不是最优解。面对误报先回答三个问题是不是输入类型没写清楚导致规则只能按最保守方式判断是不是当前上下文有特殊约定需要选优豁免是不是规则本身不适合这个项目有更合适的替代方案如果确实要豁免我建议采用行级或文件级的显式注释而不是全局关闭。全局关闭等于承认这条规则失效以后再想开回来阻力极大。行级豁免至少留下一个痕迹让后来人知道这里是被有意放过的。6. 什么时候该用什么时候别硬上6.1 适合使用 anti-slop 场景正在建设新前端工程还没有历史包袱的时候最适合引入。新项目的规则从第一天就保持严格后面维护成本会低很多。TypeScript 项目、多模块项目、多人协作项目也适合。规模越大代码风格和边界处理越需要被统一。如果是个人项目自己说了算规则松一点无所谓一旦有第二个人参与规则就成了协作契约。有大量 AI 生成代码的团队也需要这一套。AI 辅助工具越来越多代码库里的“能力垃圾”会快速增长。严格 lint 至少能把最有问题的部分拦截住。6.2 不适合硬上的场景只有一个例外级别的旧项目全仓代码已经混乱到无法快速修复这时候不要一上来就全开 error。规则是对的但落地节奏要错开。先把新代码和改动文件纳入严格检查存量代码单独列一个清理任务。还有一个场景团队成员没有接受度。如果大家不理解为什么要有观点只把 lint 当作“领导要的检查”那么再好的规则也会被绕过。你可以先跑一两次示例用真实报错说明哪些问题会导致线上故障而不是堆术语。6.3 渐进式落地的一个可用节奏我推荐下面这个节奏第一周安装 Oxlint只开默认配置跑通命令输出基线数据。第二周把 anti-slop 风格倾向明显的规则加到 warn全仓盘点问题量。第三周清理新代码和重要模块把这部分规则改成 error。第四周接 CI制定“不得新增违规”门禁。之后按模块继续清理历史问题逐步将 warn 升级为 error。与其一次推到全量不如让规则在一个稳定范围内先运转起来。lint 是长期机制不是一次性搬家。6.4 长期维护时把自己从“用户”变成“维护者”最后想说的是任何规则集都不应该是一成不变的。项目会变化依赖会升级团队习惯会调整。真正的 anti-slop 不是某个静态文件而是一套持续维护的规则策略。每隔一两个季度应该重新审视一次配置文件。把已经长期零告警的规则继续保留把误报频繁且没有实际收益的规则降级把新出现的问题模式补充进去。规则集如果三年不变它就不是门禁而是一块需要拆掉的旧墙。踩过这些坑之后我的体会是很多所谓 lint 问题都不是工具能力不够而是前置环境和输入材料没有处理干净。anti-slop 给我的最大启发不是“把规则配满”而是明确说出哪些东西不可以。当你开始认真定义“不可以”代码质量才会真的往前走。
返回列表