
解读 eslint-plugin-unicornsingle-line-block-comment-style规则基于 AVA 快照报告的完整行为剖析【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本文以 eslint-plugin-unicorn 仓库中的 AVA 快照报告 test/snapshots/single-line-block-comment-style.js.md 为主线结合规则实现 rules/single-line-block-comment-style.js、官方文档 docs/rules/single-line-block-comment-style.md 与测试用例 test/single-line-block-comment-style.js逐条拆解该规则在multiline与single-line两种风格下的错误判定、消息文案与自动修复行为。读完本文你将理解快照测试如何固话 ESLint 规则的行为掌握该规则的边界情况缩进、换行符、指令注释、空内容并能独立阅读本仓库中其他规则的.snap/.md快照报告。快照报告是什么一条规则行为的「行为固化」test/snapshots/目录下存放的是 AVA 测试框架生成的快照报告。每个*.js.md文件与同名*.js.snap文件一一对应例如test/snapshots/single-line-block-comment-style.js.md人类可读的渲染版test/snapshots/single-line-block-comment-style.js.snapAVA 实际比对的数据文件它们的来源是测试文件 test/single-line-block-comment-style.js 中ruleTest.snapshot({...})块里的invalid用例。快照机制的原理是第一次运行时 AVA 将每个 invalid 用例的输入代码、错误消息含行列位置与高亮标记、修复后输出原样记录下来此后每次运行都逐字节比对任何行为变化都会导致快照失败从而把规则行为「固化」下来。当规则行为被有意调整时开发者通过npm run fix:snapshots对应ava --update-snapshots见 package.json重新生成快照。快照报告中每个用例的标注形式为invalid(N): 输入代码摘要随后依次给出 Input传给 ESLint 的原始代码含行号与␊换行符标记Options:仅当显式传入选项时出现本次运行的规则选项 Error 1/1错误详情Message后是被标记的行与列位置Output是应用自动修复后的代码。本规则的快照报告共包含 14 个 invalid 用例前 8 个invalid 1–8对应默认的multiline风格后 6 个invalid 9–14对应显式传入的single-line风格。规则职责与默认配置根据 docs/rules/single-line-block-comment-style.md该规则「Enforce a consistent style for single-line block comments」即强制内容只占一行的独立块注释采用统一排版。它同时作用于普通块注释/* ... */与文档注释/** ... */但有明确的豁免清单内容占多行的注释紧贴代码放置非独立成行的块注释常见工具指令注释ESLint、TypeScript、格式化器、覆盖率、压缩器等带星号前缀的文档注释/**\n * x\n */这类*对齐写法以/*!开头的许可License注释。在 rules/single-line-block-comment-style.js 的规则元数据中可以看到rules/single-line-block-comment-style.js#L227-L243type: layout纯排版类规则不影响运行语义docs.recommended: true在recommended配置中默认开启fixable: whitespace仅涉及空白/换行的修改可由--fix安全自动修复defaultOptions: [multiline, {ignore: []}]默认风格为multiline默认无忽略模式schema的第一个参数是enum: [multiline, single-line]第二个参数是{ignore: Arraystring | RegExp}rules/single-line-block-comment-style.js#L202-L222。规则的消息模板为Use a {{style}} block comment.rules/single-line-block-comment-style.js#L28-L30{{style}}会被替换为multiline或single-line这正是快照中所有报错文案「Use a multiline block comment.」/「Use a single-line block comment.」的出处。默认multiline风格单行注释须拆为多行invalid 1–8默认选项下内容只有一行且独立成行的块注释会被要求改写为「分隔符各占一行」的多行形式。快照 invalid(1) 与 invalid(2) 是最典型的两例// 输入invalid 1 /** Get the value. */ // 错误 Use a multiline block comment. // 自动修复输出 /** Get the value. */普通注释/* Get the value. */的修复同理输出/*\nGet the value.\n*/。这两条用例展示了规则的核心判定与修复形态内容行独立于/*与*/之间且不引入额外的*前缀——注意修复结果没有使用 JSDoc 风格的*对齐而是保持内容裸行这是该规则与一些其他注释风格规则的关键差异。带缩进的注释行前缀的继承invalid 3快照 invalid(3) 展示了一个容易被忽略的细节当注释位于代码块内部、前面带有\t制表符缩进时// 输入 /** Get the value. */ // 修复输出 /** Get the value. */修复结果在开头定界符/**、内容行和结束定界符*/前都补齐了与原始行一致的缩进。源码中由getLinePrefix负责提取注释所在行的前缀sourceCode.text.slice(getLineStart(...), start)rules/single-line-block-comment-style.js#L61getProblem在构造修复文本时将其拼入每一行rules/single-line-block-comment-style.js#L160-L162。这意味着该规则可以安全地作用于if块、函数体等任意嵌套层级不会破坏缩进结构。行尾紧跟代码多行换行符的推断invalid 4invalid(4) 的输入是/** Carriage return value. */\r\nconst value 1;即注释后面跟的是CRLF\r\n换行且后面还有代码。修复输出为/** Carriage return value. */ const value 1;关键点在于修复产生的换行符与文件原有换行风格保持一致此处为\r\n。实现上getLineEnding按优先级推断换行符先看注释内容里已有的换行再看注释行尾的换行、注释前的换行、文件首个换行最后回退到\nrules/single-line-block-comment-style.js#L70-L75。测试文件 test/single-line-block-comment-style.js 中还有针对\r、\u2028行分隔符、\u2029段分隔符的用例test/single-line-block-comment-style.js#L344-L362快照 invalid(4) 只是其中 CRLF 的代表性一例。多星号开头/*** Value */的规范化invalid 5invalid(5) 输入/*** Value */三个星号开头修复输出为/* ** Value */这里有两个值得注意的行为开头定界符被规范化为/*内容则保留多余的星号** Value。源码中getOpeningDelimiter的判定逻辑是文本以/**开头且第 4 个字符不是*时使用/**否则使用/*rules/single-line-block-comment-style.js#L77。/*** Value */满足「/**后紧跟*」的条件因此按普通注释处理为/*。同时hasAsteriskPrefix只对内容行以*开头的文档注释放行rules/single-line-block-comment-style.js#L122-L123这里星号在内容行首** Value而非行内仍会被修复。测试文件对/*\n*\n*/、/***/、/* * */等星号边界情况均有覆盖test/single-line-block-comment-style.js#L88-L89、test/single-line-block-comment-style.js#L409-L419。定界符与内容同行混合位置的收敛invalid 6–7invalid(6) 输入/** Value.\n*/内容行与/**同行*/独占一行invalid(7) 输入/* Value.\n*/。二者虽然看起来已是「两行」但因为内容行与开头定界符共处一行仍被判定为需要修复统一收敛为三行形式/** Value. */这印证了规则的核心判定标准内容必须独占一行且与两个定界符都不在同一行。对应源码中getSingleContentLine只提取非空内容行并检查其唯一性rules/single-line-block-comment-style.js#L112-L120而「内容行与定界符同行」的情况不会被isCanonicalMultiline识别为合规多行isCanonicalMultiline要求恰好三行且首尾行为空rules/single-line-block-comment-style.js#L125-L128。前置空行与后续代码的保留invalid 8invalid(8) 的输入在注释前有一行空行、注释后紧跟const value 1;// 输入 空行 /** Value. */ const value 1; // 修复输出 空行 /** Value. */ const value 1;修复只替换注释自身的rangefixer.replaceTextRange前导空行与后续代码原封不动体现了getProblem中基于sourceCode.getRange(comment)的精确定位修复rules/single-line-block-comment-style.js#L136、rules/single-line-block-comment-style.js#L168。single-line风格多行注释须合并为单行invalid 9–14当配置为[error, single-line]时规则行为完全反转内容只有一行、却被拆成多行的独立注释需要合并为单行。这组用例在快照中带有Options: - single-line标注。invalid(9) 与 invalid(10) 是最典型的两例// 输入invalid 9文档注释 /** Another value. */ // 错误 Use a single-line block comment. // 修复输出 /** Another value. */普通注释/*\nAnother value.\n*/的修复为/* Another value. */。源码中single-line分支的修复逻辑是${opening} ${singleContentLine} */即定界符与内容之间各补一个空格rules/single-line-block-comment-style.js#L172-L181。CRLF 与缩进的还原invalid 11–12invalid(11) 输入/**\r\nCarriage return value.\r\n*/CRLF合并后输出/** Carriage return value. */——合并过程自然消除了内部换行无需关心换行符种类。invalid(12) 则是有缩进的 CRLF 变体输入\t/**\r\nCarriage return value.\r\n\t*/首行带\t末行带\t合并结果为\t/** Carriage return value. */只保留首行的缩进。这与multiline方向的「每行补前缀」形成镜像single-line方向把多行压回一行时以首行前缀为准。结束定界符与内容同行invalid 13–14invalid(13) 输入/**\nValue. */*/与内容同行invalid(14) 输入/*\nValue. */。与multiline方向的 invalid(6–7) 对称这里同样被判定为「非规范多行」合并为/** Value. *///* Value. */。两条用例共同说明无论内容挂在哪个定界符上只要内容只有一行且布局不规整规则都会介入。判定流程与豁免机制从源码看规则的「不做什么」快照只展示了「报错 修复」的一面要理解规则的完整行为还需结合其豁免逻辑。getProblem的判定顺序如下rules/single-line-block-comment-style.js#L130-L182非Block类型注释如行注释//直接跳过注释不独立成行行首或行尾有其他非空白内容直接跳过——这就是const value /* Get the value. */ 1;不会被报错的原因测试文件中有多处此类 valid 用例test/single-line-block-comment-style.js#L28-L31以/*!开头的许可注释直接跳过命中指令注释或用户ignore模式直接跳过。指令注释的识别在 rules/single-line-block-comment-style.js#L13-L26 中通过三组正则完成DIRECTIVE_PATTERNSeslint(-env)、jshint、jslint/tslint、jscs、globals、exported、flowlint、::Flow 类型别名、flow-include、c8/istanbul/nyc/v8 ignore、biome/deno/dprint/oxlint/prettier系列、cspell/spell-checker等LANGUAGE_DIRECTIVE_PATTERNSts-*、jsx*、flow、jest-environment、noformat、noprettier、$FlowFixMe/$FlowExpectedError等MINIFIER_DIRECTIVE_PATTERN__PURE__、#__NO_SIDE_EFFECTS__等压缩器指令。此外ESLint 自身的disable/disable-next-line/disable-line/enable指令通过 rules/utils/eslint-directive.js 的isEslintDisableOrEnableDirective判定其内部使用sourceCode.getDisableDirectives()精确匹配注释节点。测试文件中的/* eslint-disable no-console */、/* ts-ignore */、/* prettier-ignore */、/* c8 ignore next */等 valid 用例test/single-line-block-comment-style.js#L32-L107逐一验证了这些豁免路径。同时注意正则的边界精确性测试中有/* prettier-ignorefoo */、/* ts-ignore-foo */、/* __PURE__ extra */这类 invalid 用例test/single-line-block-comment-style.js#L421-L454说明指令模式要求严格匹配(?:\s|:|$)边界拼写变体不会获得豁免——这一点在快照中虽未列出但通过测试文件可以交叉验证。ignore选项自定义豁免模式除内置指令外规则还提供ignore: Arraystring | RegExp选项docs/rules/single-line-block-comment-style.md#ignore。字符串会被当作正则解释模式作用于去掉定界符与文档注释星号前缀后的注释文本可用^/$锚定不锚定则匹配任意位置。官方文档示例unicorn/single-line-block-comment-style: [ error, multiline, { ignore: [ ^Generated, /^License:/u, ], }, ]配置后/* Generated comment. */不再报错而/* This comment is not ignored. */仍会报错。测试文件确认了该选项与默认值[multiline, {ignore: []}]的行为test/single-line-block-comment-style.js#L292-L303。实现上getIgnorePatterns会把字符串转换为u标志的正则对 RegExp 则克隆其 source 与 flagsrules/single-line-block-comment-style.js#L106-L108且isIgnoredByPattern在每次测试前重置lastIndexrules/single-line-block-comment-style.js#L89-L95确保带g/y标志的正则也能被反复安全使用。幂等性保证修复可反复应用快照只展示一次修复的结果而测试文件额外用test(autofixes are idempotent, ...)验证了修复的幂等性test/single-line-block-comment-style.js#L550-L616通过new Linter().verifyAndFix对同一代码连续执行两轮修复断言两轮输出一致且无残留错误。例如/* Value */→/*\nValue\n*/默认模式与/**\nValue\n*/→/** Value */single-line 模式都在用例表中。这意味着用户放心执行eslint --fix不会产生「修复后再报错」的振荡。如何在本地复现与更新快照要亲自验证本文所述行为可遵循仓库的测试约定安装依赖后运行单条规则测试npx ava test/single-line-block-comment-style.js全部测试npm run test:js即ava见 package.json有意修改规则实现后用npm run fix:snapshots重新生成test/snapshots/下的.snap与.md文件再配合git diff审查行为变化是否符合预期。小结通过 test/snapshots/single-line-block-comment-style.js.md 这份快照报告可以完整还原single-line-block-comment-style规则的双向行为multiline默认把内容仅一行的独立块注释拆成三行自动补齐缩进、继承文件换行风格single-line把内容仅一行但布局多行的注释合并为/* 内容 */以首行缩进为准两类方向都严格限定于「内容只有一行」的注释多行内容、非独立注释、指令注释、/*!许可注释与文档星号前缀均被豁免修复通过fixable: whitespace交由--fix完成且经过幂等性测试保证。快照报告的价值正在于此它把「规则会对哪些代码说什么、改成什么」以最直观的输入/输出形式固化为可读文档既是对测试的渲染也是规则实现与官方文档之间最可靠的中间证据。阅读本仓库中其他test/snapshots/*.js.md文件如 test/snapshots/comment-content.js.md、test/snapshots/consistent-assert.js.md时均可套用本文的分析框架。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考