多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

从快照文件读懂 eslint-plugin-unicorn 的 no-empty-file 规则:67 个“空文件“判定场景全解析

从快照文件读懂 eslint-plugin-unicorn 的 no-empty-file 规则:67 个“空文件“判定场景全解析 从快照文件读懂 eslint-plugin-unicorn 的 no-empty-file 规则67 个空文件判定场景全解析【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本篇技术指南以仓库中的 test/snapshots/no-empty-file.js.md 快照报告为主体结合 规则源码、官方文档 与 测试用例系统讲解unicorn/no-empty-file规则对空文件的完整判定矩阵哪些内容会被视为空、哪些扩展名会被覆盖、allowComments选项如何改变判定行为以及如何通过 AVA 快照验证规则行为。读完本文你将能够准确预测任意一种文件内容在该规则下的报错行为并能自行运行测试、理解快照输出格式。快照文件是什么AVA 自动生成的规则行为证据链test/snapshots/no-empty-file.js.md是测试框架 AVA 为test/no-empty-file.js生成的快照报告文件头部明确说明Snapshot report fortest/no-empty-file.jsThe actual snapshot is saved inno-empty-file.js.snap.也就是说.md是可读的快照展示版.snap才是 AVA 实际比对的文件。整个快照覆盖67 个 invalid 测试用例编号 invalid(1) 至 invalid(67)每个用例都完整记录了输入代码、错误信息统一为Empty files are not allowed.以及报错位置的行列指示^指向的行与列。快照的价值在于它是可验证的判定证据与 test/no-empty-file.js 中的测试数据一一对应任何改动若导致报错行为变化AVA 都会报告快照不一致。因此阅读快照文件等同于阅读一份规则行为的完整清单。规则核心什么样的文件会被判定为空根据 docs/rules/no-empty-file.md该规则的目标是禁用空文件——无意义的空文件会污染代码库。快照中所有报错的 Message 均为Empty files are not allowed.官方文档列出了会被判定为空的内容清单快照对这七类内容逐一进行了验证空白字符空格、Tab、换行、回车、CRLF、BOM纯注释// comment、/* comment */、!-- comment --、# comment指令directive如use strict;、use asm;空语句;、;;空块语句{}、{;;}、{{}}YAML 文档标记与无值的元数据---、...、%YAML 1.2、anchor、!tagHashbang#!/usr/bin/env node。而只要有任意一个真实语句文件就不再为空。快照对应的 valid 用例见 test/no-empty-file.js验证了const x 0;、;; const x 0;、use strict;\nconst x 0;、{ use strict; }、(() {})()等情况全部通过。快照逐类拆解invalid(1) ~ invalid(20) 的 JS 空文件判定快照前 20 个用例全部使用example.js系统性地覆盖了 JavaScript 的空形态用例输入内容判定要点invalid(1)空文件最基本的空文件invalid(2)BOM\u{FEFF}可见为仅含 BOM 也算空invalid(3)空格仅含空格算空invalid(4)Tab\t仅含制表符算空invalid(5)~(8)\n、\r、\r\n、空串各种换行组合均算空invalid(9)// comment纯行注释invalid(10)/* comment */纯块注释invalid(11)#!/usr/bin/env nodehashbang 不算内容invalid(12)use asm;指令directive不算内容invalid(13)(14)use strict;/use strict单双引号指令均不算内容invalid(15)空字符串字面量语句invalid(16)(17);/;;空语句invalid(18){}空块语句invalid(19)(20){;;}/{{}}嵌套空块仍为空从 is-empty-node.js 源码可见判定逻辑export default function isEmptyNode(node, additionalEmpty) { const {type} node; if (type BlockStatement) { return node.body.every(currentNode isEmptyNode(currentNode, additionalEmpty)); } if (type EmptyStatement) { return true; } return Boolean(additionalEmpty?.(node)); }即BlockStatement会递归检查内部所有节点是否为空EmptyStatement直接视为空其余节点交给 is-directive.js 判断是否是指令const isDirective node node.type ExpressionStatement typeof node.directive string;ExpressionStatement且带directive字符串属性的即use strict这类指令同样被归入空。这正是 no-empty-file.js 规则源码 中isEmpty辅助函数的判定依据。allowComments 选项invalid(21) ~ invalid(27) 的语义边界快照从 invalid(21) 开始引入Options: allowComments: true专门验证该选项的边界语义invalid(21) / invalid(22)空文件、纯空格文件在allowComments: true下依然报错——该选项只放宽纯注释不放宽纯空白invalid(23) / invalid(24)仅 hashbang、#!/usr/bin/env node// comment的组合依然报错——hashbang 不是注释invalid(25); // comment依然报错——空语句 注释不算只含注释invalid(26)use strict; // comment依然报错——指令 注释同样不算invalid(27){/* comment */}依然报错——注释被块包裹后不再是顶层注释。这组用例精确刻画了allowComments的语义它只允许整个文件仅由顶层注释构成的情况。官方文档 docs/rules/no-empty-file.md 中的说明与此完全一致This allows files that only contain comments. Files with only a hashbang, directives, empty statements, empty block statements, YAML document markers, or YAML metadata without a value are still reported.配置示例unicorn/no-empty-file: [ error, { allowComments: true, }, ]默认值为false见 规则源码 的defaultOptions: [{allowComments: false}]。跨语言与跨扩展名覆盖invalid(28) ~ invalid(67)该规则不只针对 JS。快照验证了多种扩展名与语言解析器下的空文件判定对应 规则源码 中声明的languages列表invalid(28) ~ invalid(34)example.mjs、example.cJs大小写不敏感、example.ts、example.tsx、example.jsx、example.MTS、example.cts中仅含{}均报错——规则对 JS/TS 家族一视同仁invalid(35) ~ invalid(42)md、vue、svelte、astro、css、txt、html的完全空文件均报错invalid(43)HTML 文件仅含空格与 Tab 也报错invalid(44)HTML 仅含!-- comment --报错allowComments未开启时invalid(45) ~ invalid(47)CSS 空文件、空白文件、纯/* comment */均报错invalid(48) ~ invalid(50)Markdown 空文件、空白文件、纯 HTML 注释均报错invalid(51) ~ invalid(60)YAML 空文件、空白文件、# comment、%YAML 1.2、anchor、!tag、---、...等文档标记均报错其中即使开启allowComments%YAML 1.2 # comment、anchor # comment、!tag # comment、--- # comment、... # comment组合依然报错——YAML 元数据标记本身不算内容invalid(61) / invalid(62).gitignore空文件与空白文件报错但错误信息中没有任何^指示符见快照Message 下无行列标记——因为纯文本解析器eslint-parser-plain产出的 AST 没有任何 token 可供定位invalid(63) ~ invalid(67)TOML 空文件、空白文件、# comment均报错allowComments只对纯注释 TOML 生效对应 valid 用例# commentwithallowComments: true。快照还反映了一个重要事实普通 JSON 文件无法为空语法错误但 JSONC/JSON5/YAML 等可以只有注释仍会被规则判定为空见官方文档说明。此外处理器processor抽取出的代码片段不算文件例如 Markdown 中围栏代码块被抽取后即使是空块也不会被报错——这对应 规则源码 中context.filename ! context.physicalFilename的提前返回判断。快照中的特殊豁免场景不报错虽然本文聚焦的快照文件记录的是 invalid 用例但结合 test/no-empty-file.js 的 valid 用例与 规则源码可以看到规则刻意豁免的场景理解这些豁免有助于避免误报TypeScript 三斜线指令/// reference typesexample /是有效内容d.ts、ts均豁免对应源码中hasTripleSlashDirectives判断no-empty-file.jsVue SFC 带template即使script为空也不报错因为templateBody存在即视为有内容no-empty-file.jsHTML 存在非注释子节点divHello/div、!DOCTYPE html不报错no-empty-file.jsMarkdown 有可见文本!-- a -- text !-- b --不报错——注释之间的可见文本算内容非空文件但 AST 为空.gitignore、.editorconfig这类被eslint-parser-plain解析的文件即使 AST 无 token 无注释只要sourceCode.text.trim() ! 就不报错no-empty-file.js——这是为了避免把有内容的纯文本文件误判为空JSON 文档存在值node.body ! null node.body ! undefined即视为有内容no-empty-file.js。如何在本地复现快照快照由 AVA 在运行测试时自动生成与比对。要复现本文的全部判定场景可在仓库根目录执行npm install npm test -- --match*no-empty-file*或直接运行npx ava test/no-empty-file.js运行后AVA 会将test/no-empty-file.js中每个用例的实际输出与test/snapshots/no-empty-file.js.snap比对若规则行为被改动导致输出变化会在test/snapshots/no-empty-file.js.md中反映出来。仓库还提供了 test/utils/test.js 之类的测试辅助设施含getTester、parsers、languages用于按语言解析器组织用例。需要注意的是本文引用的快照内容以当前仓库状态为准若你使用的eslint-plugin-unicorn版本不同快照与规则行为可能存在差异请以你所安装版本对应的文档 docs/rules/no-empty-file.md 为准。小结通过逐条解读 no-empty-file.js.md 快照的 67 个用例我们可以得出unicorn/no-empty-file规则的完整判定模型判定标准是AST 层面是否存在真实内容空白、注释、指令、空语句、空块、hashbang、YAML 标记都被视为空allowComments只放宽纯顶层注释场景对空白、指令、hashbang、YAML 元数据等依旧报错规则覆盖 JS/TS 全家族与 md/vue/svelte/astro/css/html/txt/yaml/toml 等多种语言并对各语言解析器的 AST 结构Program、StyleSheet、Document、root、YAML 文档节点分别处理存在多种刻意豁免避免对处理器抽取块、带template的 Vue SFC、纯文本解析器等场景误报。这份快照既是规则的行为契约也是排查为什么我的文件被报空/没被报空的最佳参考清单。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表