想象你经营一家餐厅:十几位厨师同时出菜,菜单上写着同一道“回锅肉”,端上来的成品却五花八门——有人放三勺盐,有人摆盘歪斜,有人偷偷用了不新鲜的食材。如果等客人投诉才整改,口碑早就垮了。于是你增设一个“后厨质检员”岗位:每道菜出锅、上桌前,都必须照着那册《出品标准》从头到尾验一遍。软件开发的 PR(Pull Request)流程,恰恰就是这样的“出菜口”——而代码规范 Linting,就是站在出菜口把关的那位质检员。 在 GitHub 上给开源项目提 PR 时,维护者最不愿看到的,就是代码风格五花八门、低级错误满屏飞。Linting 工具能自动扫描代码,揪出格式问题、潜在 bug 和“坏味道”,并在代码合入主干之前亮红灯。这篇文章会用“餐厅后厨”这个场景,把 Linting 的原理、工具、配置、PR 集成、性能优化与团队协作讲透,让你从“听说过 Lint”进阶到“能独立给开源项目贡献高质量代码”。

岗位关联

对 AI 从业者而言,Linting 是开源贡献与团队协作的“入场券”:它让代码评审聚焦逻辑而非格式,让你的 PR 更快被合入,也让 AI 项目的实验代码库保持长期健康。

目录
  1. 可视化演示
  2. 基础概念入门
  3. 主流工具生态
  4. 规则配置管理
  5. PR流程集成
  6. 自动修复优化
  7. 团队协作规范
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示PR流程中代码规范检查:pre-commit钩子(flake8+black+isort)、CI流水线(GitHub Actions lint门禁)、规则分类统计(E错误/W警告/C复杂度),切换步骤查看。

本节配有交互动效(进入视口后自动加载,约 3KB)。

pre-commit钩子 git commit触发flake8+black+isort pre-commit run --all-files 本地拦截不规范代码提交

基础概念入门

回到那家餐厅。质检员的工作不是亲自炒菜,而是等菜出锅后,对照《出品标准》逐项验收:盐放了几克、摆盘是否整齐、食材新不新鲜。他不需要把菜重新做一遍,只需要“看”和“量”。软件世界的 Linter 也这样——它不运行你的代码,而是像读菜谱一样一行行“读”源代码,比照预设规则找出可疑之处。这种不执行程序、只分析源码的做法,叫作静态分析。

Lint 这个词源自 1978 年贝尔实验室的一个 C 语言工具,本意是检查程序中“可能有害”的写法。四十多年后,它演化成所有编程语言都离不开的质检体系。Linter 能查的问题大致分三类:格式类(缩进、分号、引号风格)、隐患类(变量声明了没用、条件恒为真、隐式类型转换)、坏味道(嵌套过深、函数过长、重复代码)。第一类让代码“好看”,第二类让代码“不炸”,第三类让代码“好改”。

如何量化一个 PR 的卫生程度?我们给每类问题赋一个权重,命中次数越多、权重越大,风险分越高:

质检员不会天天改菜谱,但会天天记台账。Linter 的价值正在于此:它把“我觉得这菜不对劲”变成“这里的风险分是 7.5,超过 5.0 的门禁线,不能上桌”。这种客观、可复现、不依赖个人情绪的检查,正是开源项目维护者敢把合入门禁交给它的原因。

R=∑i=1nwi×ni\displaystyle R = \sum_{i=1}^{n} w_i \times n_i
风险分 R 是所有违规问题的加权总和:以 ESLint 为例,error 级问题权重高、warn 级权重低,团队可设定“R 超过某阈值就拒绝合并”。
  1. 第 $i$ 类问题i=1,2,…,ni = 1, 2, \ldots, n 表示 Linter 检查的规则类别,例如“尾随空格”“超长行”“未使用变量”,每一类都对应一条规则。
  2. 权重 $w_i$wiw_i 是第 $i$ 类问题的严重程度系数。问题越可能引发线上故障,权重越大;这只是提示性质的规则,权重就小。
  3. 命中数量 $n_i$nin_i 是第 $i$ 类问题被 Linter 实际检测到的次数,出现一次记一次。
  4. 累加求和∑i=1nwi×ni=w1n1+w2n2+⋯+wnnn\displaystyle \sum_{i=1}^{n} w_i \times n_i = w_1 n_1 + w_2 n_2 + \dots + w_n n_n 把所有类别的加权值相加,得到这份 PR 的总风险分。

主流工具生态

后厨质检不能只靠一个人一把尺。不同菜系有不同标准:川菜看火候、粤菜看鲜度、甜品看造型。软件世界也一样,不同语言、不同用途各有专门工具。

JavaScript/TypeScript 生态的质检主力是 ESLint。它的核心特点是“规则即插件”:官方提供一批基础规则,社区贡献了海量插件,从 React 的组件规范到 Node.js 的安全隐患都能覆盖。Prettier 则更像“摆盘师”——它不判断代码对错,只负责把缩进、换行、引号统一成一种风格,让所有厨师端出来的菜摆盘一模一样。Stylelint 专盯 CSS/SCSS 等样式代码,帮助团队维持设计规范的秩序。其他语言也各有利器:Python 有 Ruff、Flake8、Black,Go 有 golangci-lint,Rust 有 Clippy。

选工具的时候,团队常犯的错是把“格式化”和“规范检查”混为一谈。精确率的概念能帮我们评估一个 Linter 值不值得信任:

一把好尺子,量得准比量得多更重要。Prettier 管“盘子里长什么样”,ESLint 管“这菜能不能吃”,Stylelint 管“盘子裂没裂”。三者各司其职、相互配合,后厨才能既美观又安全。

Precision=TPTP+FP\displaystyle Precision = \frac{TP}{TP + FP}
精确率衡量“Linter 报的问题里,真正值得修的占比”。误报太多会让团队对质检员失去信任,最终全员无视警告。
  1. 真阳性 $TP$TPTP 是 Linter 正确报出的真实问题数量。比如它指出“这个变量定义了没用”,你一看,确实没用。
  2. 假阳性 $FP$FPFP 是 Linter 报错但实际没问题的数量。比如它嫌你的命名单词太短,但那个变量就是惯例写法。
  3. 精确率计算TPTP+FP\displaystyle \frac{TP}{TP + FP} 分子是真正有用的报告,分母是所有报告。精确率接近 1,说明质检员“每报必中”。
  4. 解读如果某个规则频繁误报,团队会产生“狼来了”效应。这时应该调低它的权重,甚至直接关闭。

规则配置管理

《出品标准》不是凭空定的,它写在后厨墙上,隔月更新一次。Linter 的规则同样沉淀在配置文件里:ESLint 使用 .eslintrc.js(新版也支持 eslint.config.js 扁平配置),里面声明了环境、解析器、插件和每一条规则的开关。

每条规则有三个档位,对应质检员的三级处置方式:off(0)——这条不查,相当于“此菜不做硬性要求”;warn(1)——记一笔但不拦菜,相当于“提醒你下次注意”;error(2)——立即拦截,相当于“这道菜不准上桌”。规则级别和风险分直接挂钩,error 的问题会让 R 迅速飙升。

插件是配置管理的放大器。社区里的 eslint-plugin-react、eslint-plugin-vue 就像外聘的专项顾问:你不需要自己发明“组件必须写 propTypes”这类规则,装上插件就有现成的一整套标准。更进一步,团队还能基于抽象语法树(AST)编写自定义规则,实现“这家店特有的规矩”。共享配置(如 eslint-config-airbnb、eslint-config-standard)则像连锁总店的统一手册,新分店开张时直接复制一份即可。

配置的松紧需要数据支撑。某条规则要不要从 warn 升到 error?看它的误报率:

规则配置的本质是团队共识的编码化。它把“小张觉得缩进要两格,小李认为四格更清楚”这种无尽争吵,变成一次性的配置评审。守则写清楚、分档合理、误报可控,后厨才能把精力留给真正的难题——而不是每天争论盐放几克。

FPR=FPFP+TN\displaystyle FPR = \frac{FP}{FP + TN}
误报率指“本来没问题的代码被误判违规”的比例。误报率高的规则升为 error,只会让合入门禁变成“碰运气”。
  1. 假阳性 $FP$FPFP 是本来没问题的代码被判违规的次数。例如代码风格完全合规,却因为“变量名必须三个字母以上”被报错。
  2. 真阴性 $TN$TNTN 是本来没问题且正确放行的次数。质检员扫过一段合规代码,没有报警,这就是一次真阴性。
  3. 误报率计算FPFP+TN\displaystyle \frac{FP}{FP + TN} 分子是误伤次数,分母是所有“本来没问题”的代码量。误报率越高,规则越“神经质”。
  4. 决策依据如果新规则在试行阶段的误报率超过 20%,应该继续留在 warn 档观察,而非直接升为 error。

PR流程集成

质检员不能只在菜快上桌时才出现,他应该守在每一道关卡。软件开发里,Linting 要嵌入 PR 流程的多个节点,形成层层拦截。

第一道关卡是本地 Git Hook。借助 husky 这类工具,Git 会在 pre-commit(提交前)、pre-push(推送前)自动触发 Lint。这相当于厨师出菜前自己先照一遍镜子:衣服没系好、帽子歪了,先在里屋整理好,别端出去丢人。第二道关卡是 CI 门禁——代码推到 GitHub/GitLab 后,CI 流水线中的 Lint 任务开始跑,结果会以“✅ 通过 / ❌ 失败”的形式挂在 PR 页面。这是质检员站在出菜口的正式验收:失败就别想合入。

门禁的判断逻辑可以用一个门禁函数描述:设定风险分阈值 T,低于阈值放行,高于阈值拦截。

这三道关卡组成反馈闭环——本地 Hook 让问题在 1 分钟内暴露,CI 门禁兜住漏网之鱼,PR 页面让修改记录全程可追溯。开源贡献者最怕的是“改十行代码等半小时 CI”,所以本地 Hook 不是可选项,而是必须项。

G(R,T)={1R≤T0R>T\displaystyle G(R, T) = \begin{cases} 1 & R \le T \\ 0 & R > T \end{cases}
门禁函数 G 把“风险分是否超标”变成二进制决定:1 表示合并,0 表示拦截。开源项目把这道门禁写成 CI 配置,任何人都无法绕过。
  1. 风险分 $R$RR 来自第一节的加权求和公式,是本次 PR 所有 Lint 问题的总风险度量。
  2. 阈值 $T$TT 是团队预先定义的门禁线。比如“error 问题数最多 0 个 + warn 问题数最多 10 个”,折算成 R 的阈值。
  3. 放行条件1ifR≤T1 \quad \text{if} \quad R \le T 当风险分不超过阈值,门禁放行,PR 可以进入人工评审。
  4. 拦截条件0ifR>T0 \quad \text{if} \quad R > T 当风险分超标,门禁拦截,PR 作者必须修复或逐条豁免。

自动修复优化

质检员发现摆盘歪了,不会让厨师重新炒一盘——他直接伸手把盘子转正。Linter 也一样:ESLint 的 --fix 参数能自动修复格式类问题,比如去掉尾随空格、统一引号、补分号。这类修复是机械的、安全的,相当于质检员顺手拧紧松了的瓶盖。

真正麻烦的是大仓库的性能。几万行代码每次全量扫描,好比把整个后厨的柜子全翻一遍才能端出一道菜。优化思路是“只查该查的”。增量检查只扫描本次 PR 改动的文件;缓存机制(如 .eslintcache)记录上次检查结果,文件没变就直接跳过;忽略策略通过 .eslintignore 把 node_modules、构建产物等“非食材区域”排除在外。工具 lint-staged 则更进一步:只对暂存区(准备提交的那几个文件)执行检查。

增量检查加速效果可以用一个简单比例估算:

优化的终点不是“快”,而是“快到让人愿意每次提交都跑”。当 Lint 从 3 分钟缩到 3 秒,开发者会主动在本地频繁执行,而不是把质检全部丢给 CI——后厨的自检习惯,就这样养成了。

TchangedTfull≈DchangedDall\displaystyle \frac{T_{changed}}{T_{full}} \approx \frac{D_{changed}}{D_{all}}
只查改动文件时的耗时,近似等于“改动文件数 / 仓库总文件数”。一个 2000 文件的仓库,PR 只改了 20 个文件,理论提速 100 倍。
  1. 全量耗时 $T_{full}$TfullT_{full} 是 Linter 扫描整个仓库所需的时间,以秒或分钟计。
  2. 改动文件数 $D_{changed}$DchangedD_{changed} 是本次 PR 实际修改的文件数,通常远小于全仓总量。
  3. 仓库总文件数 $D_{all}$DallD_{all} 是仓库内所有被 Lint 覆盖的文件数。
  4. 加速比关系TchangedTfull≈DchangedDall\frac{T_{changed}}{T_{full}} \approx \frac{D_{changed}}{D_{all}} 在忽略文件大小差异的前提下,耗时与文件数近似成正比。这也是 lint-staged 广泛流行的原因。

团队协作规范

最后,质检员要回答一个根本问题:标准由谁定?如果每位厨师都带自己私藏的《出品标准》,后厨就会乱成一锅粥。团队必须把 Linting 当作公共基础设施来治理。

第一步是统一配置:把 .eslintrc.js、.prettierrc.js 抽成共享包,随项目仓库分发,新成员克隆即用。第二步是约定优先:工具解决不了的争议(比如“这个组件该不该拆”)通过团队讨论沉淀成文档,再逐步翻译成新的 Lint 规则——约定先行,工具跟进。第三步是评审联动:Code Review 中,机器负责机械问题(格式、命名、死代码),人只负责逻辑、架构和建议,避免评审变成“挑错别字大赛”。第四步是规范演进:引入破坏性新规则时,先在 warn 档观察一个迭代周期,统计误报率和团队反馈,再决定是否升为 error。

规范落地得好不好,可以用规范符合度来衡量:

后厨最怕的不是菜难吃,而是“没有标准”;软件项目最怕的不是有 bug,而是“每一次合并都在积累技术债”。当 Linting 成为团队的肌肉记忆,质检员的存在感反而会变淡——因为大家已经习惯按标准做菜,几乎不需要拦截。这正是规范治理的最高境界:让正确成为默认。

C=NpassNtotal\displaystyle C = \frac{N_{pass}}{N_{total}}
符合度 C 是“通过 Lint 的代码量 / 总代码量”。定期统计 C 的走势,团队能直观看到规范是从 60% 涨到 95%,还是停滞在 70%。
  1. 通过量 $N_{pass}$NpassN_{pass} 是本次 PR 中通过 Lint 检查的行数或文件数。
  2. 总量 $N_{total}$NtotalN_{total} 是本次 PR 涉及的行数或文件总数。
  3. 符合度计算NpassNtotal\frac{N_{pass}}{N_{total}} 比值越接近 1,说明代码越符合团队规范。
  4. 长期追踪在 CI 里定期输出 C 的数值,形成趋势曲线。若某团队 C 从 92% 跌到 85%,往往意味着新成员入职或规则刚调整,正好提醒你做一次规范宣讲。

AI 应用场景

场景一:AI 代码生成器的“第一道质检关”

阶段:代码生成后置校验

解决的问题:Copilot、Cursor 等 AI 编程助手能快速生成代码,但风格往往“千人千面”,甚至包含未使用变量、隐含的类型问题。若逐行人工审查 AI 输出,效率优势就被抵消。把 Linting 接在 AI 生成之后、合入之前,相当于给 AI 厨师配了一位固定质检员:格式问题自动修,隐患问题立即标红。

具体案例:某数据科学团队用 Copilot 生成数据处理脚本,接入 ESLint + Prettier 后,AI 产出的代码一次性通过率从 40% 提升到 85%。未能通过的部分,Linter 明确指出“变量 y 未使用”“函数超过 50 行”,开发者据此二次提示 AI 修改。

场景二:AI 实验仓库的规范治理

阶段:训练代码仓库管理

解决的问题:AI 项目里充斥着 Jupyter Notebook、训练脚本、配置文件,实验迭代极快,代码质量容易失控。为 train.py、data_loader.py 配置 Python Linter(Ruff/Flake8),为 Notebook 配置 nbqa 检查单元格代码,能避免“能跑就行”的代码债越滚越大。

具体案例:某开源大模型微调仓库引入 pre-commit Hook,配置 Ruff 检查 + Black 格式化。提交时自动拦截超长行和未使用导入,PR 的评审时间平均缩短 30%,新贡献者的代码被合入率明显提升。

Python 演示

python57 行
"""mini_linter.py - 模拟 PR 质量门禁的迷你 Linter""" import re  class MiniLinter:    """极简 Linter: 检查尾随空格与超长行两类问题"""     def __init__(self, max_line_len=88):        self.max_line_len = max_line_len        self.issues = []        self.rule_weights = {"trailing_space": 1.0, "long_line": 0.5}     def lint(self, code_lines):        """逐行检查代码, 返回 (行号, 规则名) 列表"""        self.issues = []        for line_no, line in enumerate(code_lines, 1):            if re.search(r"\s+$", line):                self.issues.append((line_no, "trailing_space"))            if len(line) > self.max_line_len:                self.issues.append((line_no, "long_line"))        return self.issues     def score(self):        """加权风险分 = 规则权重 x 命中数"""        return sum(self.rule_weights[rule] for _, rule in self.issues)     def check_pr(self, files):        """检查整个 PR 的所有文件, 返回门禁结果"""        results = {}        for path, lines in files.items():            issues = self.lint(lines)            results[path] = (self.score(), issues)        total_score = sum(s for s, _ in results.values())        return total_score <= 4.0, total_score, results  if __name__ == "__main__":    pr_files = {        "model.py": [            "def train(data):",            "    loss = compute_loss(data)  ",            "    return loss",        ],        "api.py": [            "from flask import Flask",            "app = Flask(__name__)",            '    return "hello"  ',        ],    }    linter = MiniLinter()    passed, total, details = linter.check_pr(pr_files)    print(f"PR 门禁结果: {'通过' if passed else '拒绝'}, 风险分: {total}")    for path, (score, issues) in details.items():        print(f"  {path}: 风险分={score}, 问题数={len(issues)}")        for line_no, rule in issues:            print(f"    第 {line_no} 行违反: {rule}")
目的:实现一个迷你 Linter,演示“加权风险分 + 门禁判定”的 PR 质检流程——这是 ESLint 等真实工具的核心逻辑简化版。
  1. class MiniLinter:定义质检员类,模拟真实 Linter 的角色:不执行代码,只做静态扫描。
  2. if re.search(r"\s+$", line):用正则检测行尾空格,对应 ESLint 的 no-trailing-spaces 规则。
  3. if len(line) > self.max_line_len:检查单行长度是否超过 88 字符,对应 max-len 规则。
  4. self.rule_weights = {"trailing_space": 1.0, "long_line": 0.5}给每类问题赋权重,对应第一节风险分公式中的 $w_i$。
  5. return sum(self.rule_weights[rule] for _, rule in self.issues)用生成器求和,实现 $R = \sum w_i \times n_i$。
  6. total_score <= 4.0, total_score, results门禁判定:风险分不超过 4.0 就放行,对应门禁函数 $G(R, T)$。
  7. results[path] = (self.score(), issues)每个文件单独计分,便于 PR 页面上逐文件展示检查结果。

常见误区

误区我一直以为 Linting 就是查缩进、引号、分号这些表面问题。代码能不能跑对,还得靠测试和人工 Review,Linter 帮不上忙。

正解Linter 的检查范围远超格式。以 ESLint 为例,它能提示“变量声明但从未使用”“switch 分支缺少 break”“比较时用了 == 而非 ===”“在 finally 块中 return 吞掉异常”等潜在逻辑隐患。这些不一定会让程序报错,但往往是 bug 的温床。就像质检员不仅看摆盘,也会闻一闻食材是不是有异味。

为何常见:因为最外层的 Lint 报告里,格式类问题数量最多、最显眼,初学者容易被“满屏标红都是空格”的印象带偏。

误区我刚接手项目时把所有规则都设为 error,觉得规则越严代码质量越高。结果团队成员每天花大量时间消除警告,提交频率反而下降了。

正解规则过载会让质检员变得“神经质”:误报率升高、精确率下降,团队被迫为大量低价值规则妥协。正确做法是分层治理——开箱即用的推荐集打底,再有针对性地加少量团队特性规则;新规则先用 warn 灰度观察,误报率低再升 error。

为何常见:人们容易把“严格”等同于“可靠”,却忽略了高误报率会导致团队对整个 Lint 报告脱敏,真正重要的告警反而被淹没。

误区反正推到 GitHub 后 CI 会自动跑 Lint,失败了再改也不迟。本地配 pre-commit 多此一举。

正解CI 是“出菜口的最终质检”,但它反馈周期长——推送、排队、运行、回传结果,一趟往往要几分钟到十几分钟。本地 Hook 让问题在 commit 之前、1 秒内暴露,属于“厨房里先照镜子”。两者是互补关系:本地省时间,CI 兜底线。开源项目评审者看到“每 3 个 commit 就触发一次失败 CI”的提交历史,也会对贡献者的工程素养打问号。

为何常见:新手通常先接触 CI 门禁的可见结果(PR 页面上的红绿灯),而忽略了本地 Hook 这种“看不见的加速器”。

误区Prettier 能自动把代码格式统一,那 ESLint 就没必要了,两个工具还有规则冲突,不如只留一个。

正解两者的分工是“摆盘”和“质检”,不可互相替代。Prettier 只处理格式类问题(缩进、换行、引号),不检查未使用变量、不检查逻辑隐患;ESLint 则聚焦质量规则,两者有重叠时通过 eslint-config-prettier 关闭 ESLint 的格式类规则来消除冲突。现代前端项目的标准组合是“ESLint 管质量 + Prettier 管格式”,再配合 lint-staged 串行执行。

为何常见:因为二者的报错都是“代码风格层面”的红色波浪线,初学者难以区分“格式问题”和“规范问题”的本质差异。

面试题

Q1. ESLint 配置文件最常见的默认名称是?

单选题 · easy

  • A..eslintrc.js← 正确答案
  • B..prettierrc.js
  • C..stylelintrc.js
  • D..editorconfig.js

答案:A。ESLint 使用 .eslintrc.js(或 .eslintrc.json)作为规则配置入口,相当于后厨的《出品标准》手册。Prettier 对应 .prettierrc.js,Stylelint 对应 .stylelintrc.js,编辑器编码规范用 .editorconfig——它们分工不同,不是同一本守则。

Q2. Linting 的核心工作方式是什么?

单选题 · easy

  • A.运行代码观察输出
  • B.编译后做性能剖析
  • C.不运行代码的静态分析← 正确答案
  • D.部署后监控日志

答案:C。Linter 像质检员看菜色,不把菜吃到嘴里。它通过静态分析源码结构来发现问题,不执行程序。运行代码找问题属于测试范畴,性能剖析和日志监控也都要在运行时进行,与 Lint 的“读菜谱式检查”本质不同。

Q3. Git 中在提交之前触发的 Hook 名称是?

单选题 · easy

  • A.pre-commit← 正确答案
  • B.post-merge
  • C.pre-push
  • D.commit-msg

答案:A。pre-commit 在 git commit 执行前触发,是挂载本地 Lint 的经典位置,相当于厨师出菜前照镜子。pre-push 是推送前触发,commit-msg 校验提交信息,post-merge 在合并后触发——它们各自守在流程不同节点。

Q4. ESLint 规则级别设为 2(error)时表示?

单选题 · mid

  • A.仅提示不阻断
  • B.生成警告不算失败
  • C.检查到就阻断门禁← 正确答案
  • D.忽略该条规则

答案:C。规则级别三档中,0(off)为不启用、1(warn)为警告不拦截、2(error)为报错并拦截门禁。error 相当于质检员说“这道菜不准上桌”,CI 会因此失败、PR 无法合并。warn 只是“提醒下次注意”,不会阻断流程。

Q5. Prettier 与 ESLint 的主要分工区别是?

单选题 · mid

  • A.Prettier 查逻辑而 ESLint 查格式
  • B.Prettier 管格式而 ESLint 管规范← 正确答案
  • C.ESLint 管部署而 Prettier 管测试
  • D.两者完全相同可互相替代

答案:B。Prettier 是摆盘师,统一缩进、引号、换行等视觉风格;ESLint 是质检员,检查未使用变量、潜在 bug、代码坏味道等质量规范。A 把两者说反了,C、D 更是完全混淆了各自职责。

Q6. 以下哪些属于常见的 Linting 工具?

多选题 · mid

  • A.ESLint 检查器← 正确答案
  • B.Prettier 工具
  • C.Stylelint 工具← 正确答案
  • D.Docker 容器

答案:AC。ESLint 是 JS/TS 生态的 Linter 代表,Stylelint 专盯 CSS 样式代码。Prettier 虽常用于代码规范流程,但本质是格式化工具而非 Linter。Docker 是容器化技术,与代码静态检查无关。判断标准是“是否对源码做违反规则的检测”。

Q7. PR 检查中 Lint 失败时,推荐的处理方式包括?

多选题 · mid

  • A.本地复现并修复← 正确答案
  • B.自动修复命令处理← 正确答案
  • C.直接合并绕过检查
  • D.补充规则到配置库← 正确答案

答案:ABD。Lint 失败后应先在本地用 npm run lint 复现,再用 --fix 自动修复格式问题,若发现是团队规则的遗漏,应通过更新共享配置来沉淀。直接绕过合并(如管理员强制合入)会破坏门禁公信力,让质检形同虚设。

Q8. 自定义 ESLint 规则时,主要基于什么结构分析代码?

单选题 · mid

  • A.抽象语法树(AST)← 正确答案
  • B.正则表达式全文匹配
  • C.字符串哈希比对
  • D.运行时调用栈分析

答案:A。ESLint 把源码解析成抽象语法树(AST),规则通过访问树节点来发现模式,比如“找到所有函数声明,检查是否有 return”。正则只适合简单文本,字符串哈希无法表达嵌套结构,调用栈则是运行时概念——都不适合做静态代码模式识别。

Q9. 提高大仓库 Lint 速度的常用手段有哪些?

多选题 · hard

  • A.全量扫描每次必跑
  • B.只检查改动文件← 正确答案
  • C.缓存上次检查结果← 正确答案
  • D.关闭所有检查规则

答案:BC。增量检查(只扫改动文件)和缓存机制(文件未变则跳过)是两大提速利器,lint-staged 正是前者的代表工具。全量扫描每次必跑是性能反模式,关闭所有规则则让质检失去意义——提速的前提是质量底线不破。

Q10. lint-staged 的核心作用是什么?

单选题 · extreme

  • A.只对暂存区文件执行检查← 正确答案
  • B.对所有历史代码做全量检查
  • C.在线上环境运行 Linter
  • D.替代 Code Review 流程

答案:A。lint-staged 读取 Git 暂存区(staged)中本次准备提交的文件,只对它们执行 Lint/格式化。这样一次提交只需检查几个文件,速度从分钟级降到秒级。全量扫描是它的对立面,线上运行和替代 Review 都误解了它的定位——它只是门禁链路上的一环。