eslint和sonarqube无法检测html结构问题,因其分别仅支持js解析和基于正则/简易dom的静态分析,无法理解组件嵌套、属性绑定等语义;必须借助parse5等专用html解析器生成ast,再遍历节点校验如img是否含alt属性。

为什么直接用 ESLint 或 SonarQube 检测不了 HTML 结构问题
因为 ESLint 天然只解析 JavaScript,对 .html 文件默认跳过;SonarQube 的 HTML 插件依赖静态正则或简单 DOM 解析,无法识别组件嵌套逻辑、属性绑定语义、或 JSX/模板语法中的动态结构。真正要检查 v-if 是否被误写成 v-ifs、data-testid 是否缺失、或 img 标签有没有 alt,必须走到 AST 层——不是字符串匹配,而是把 HTML 当成语法树来遍历。
用 @babel/parser 解析 HTML 会失败,该选哪个 parser
@babel/parser 不支持纯 HTML,强行启用 jsx: true 会把 <div class="x"></div> 解成 JSX 节点,丢失原生 HTML 的属性结构(比如把 class 当成 JSX 属性而非 HTML 属性)。正确选择是:parse5(主流、符合 HTML5 规范、输出标准 AST)、htmlparser2(轻量、事件驱动、适合流式处理),或 cheerio(底层用 htmlparser2,API 类 jQuery,但 AST 可访问性弱)。生产环境推荐 parse5,它输出的 document 节点带完整 childNodes 和 attributes,方便写规则时判断父子关系和属性存在性。
如何编写一条“强制 img 必须含 alt”的 AST 规则
核心不是找标签名,而是遍历所有 ElementNode,筛选 tagName === 'img',再检查其 attributes 数组里是否存在 name === 'alt'。注意三点:
-
parse5的attributes是数组,每个元素是{ name: string, value: string | null },不能用el.attributes.alt这种对象取值 - 空字符串
alt=""是合法的,应允许;但alt完全缺失才报错 - 若项目用 Vue,需额外排除
v-bind:alt或:alt绑定场景,此时应检查是否存在bindings字段或属性名是否以v-bind:开头
示例片段:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
if (node.tagName === 'img') {
const hasAlt = node.attributes.some(attr => attr.name === 'alt');
if (!hasAlt) {
report(node, 'img must have alt attribute');
}
}
插件集成到 VS Code 时,AST 分析卡顿怎么办
每次保存都全量 parse 整个 HTML 文件,在大文件(>2000 行)上会明显卡顿。根本原因是 parse5.parse() 是同步阻塞调用。解决方式只有两个:
- 加缓存:用
Map<string ast></string>缓存已解析内容,键为文件路径 + 文件修改时间戳(fs.statSync().mtimeMs),避免重复 parse - 增量分析:不重跑全树,只对比上次 AST 和当前 AST 的
node.id或sourceCode哈希,仅校验变更节点及其父链(如改了某个div,只检查它和它的祖先)
别试图用 Web Worker —— VS Code 插件 API 不支持跨线程传递 DOM 节点或 parse5 的 AST 对象,序列化成本反而更高。
AST 规则最难的不是写检测逻辑,而是准确区分“HTML 原生语法”“框架指令语法”“自定义属性语义”,比如 data-* 要不要校验格式、aria- 属性拼写是否合法、slot 在 Vue 和 Web Components 中含义不同——这些边界情况,得靠真实项目样本反复调规则,没法靠文档猜出来。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










