tag-pair规则必须启用,因其按HTML5标准严格校验开闭匹配,避免浏览器静默修复导致DOM结构不一致,如<div><p>hello</div>在Chrome与Safari中解析结果不同,引发hydration mismatch或querySelector失效,错误精确定位至行列号(如index.html:42:7),且对自闭合标签无额外要求,仅检测“有开无闭”或“闭多于开”。

tag-pair 必须启用,否则漏闭合标签会直接导致 DOM 结构错乱,浏览器静默修复后,querySelector 在 CI 环境里随机失效。
为什么 tag-pair 规则不能关
它不依赖浏览器纠错逻辑,而是按 HTML5 标准严格校验开闭匹配。比如 <div><p>hello</div> 这种错误,Chrome 可能自动补全为 <div><p>hello</p></div>,但 Safari 或 JSDOM 会解析成 <div><p>hello</div></p>,最终 React hydration mismatch 或 E2E 定位失败。
- 错误输出带精确行列号,如
index.html:42:7: Tag must be paired.,比肉眼排查快得多 - 对自闭合标签(
<img>、<br>)不做额外要求,只盯“有开无闭”或“闭多于开” - 若项目含
.vue或.ejs片段,需在.htmlhintrc中用"ignore": ["**/*.vue"]显式排除,否则误报
html-validate 怎么配语义规范才不空转
默认规则不检查语义层级,必须手动启用 heading-required、head-valid-content-model、require-lang-attribute 等项。W3C 验证器只管语法合法,而语义错误(如 <div><h1>标题</h1></div>)要靠这些规则拦截。
-
"heading-required": {"max-depth": 1}强制每个页面最多一个<h1>,避免 SEO 权重稀释 -
"head-valid-content-model": true阻止<script>错放在<head>外,防止 SSR 渲染时被忽略 -
"require-lang-attribute": true对多语言站点是刚需,单语言管理页可按路径ignore掉 - 禁用
attr-bans类宽松规则,它允许data-test-id却放行onclick,偏离工程目标
CI 里跑 html-validate 容易卡在哪几个点
不是工具不行,是配置和执行路径没对齐真实构建流程。本地能过,CI 报错,90% 是环境或路径问题。
立即学习“前端免费学习笔记(深入)”;
- 命令必须写成
npx html-validate --config .htmlvalidate.json src/**/*.html,不能依赖全局安装,也不能省略--config -
.htmlvalidate.json必须放在项目根目录,且第一行不能有 BOM 或空格——否则 Node.js 加载失败,静默退回到默认宽松规则 - 构建产物(如
dist/)不能纳入扫描范围,否则会校验已压缩、已注入的 HTML,误报大量no-inline-style或attr-lowercase - 若用 Webpack/Vite 构建,需确认插件(如
html-loader)未把<header>当纯文本吞掉——最终 DOM 缺失语义标签,校验器却看不到
真正难的不是加一条规则,而是判断某个标签该不该强制语义化:比如微前端子应用入口页没有 <title> 是合理设计,硬塞反而破坏主应用的 title 同步逻辑。规则得跟着运行时上下文走,不是贴着 WCAG 清单抄。



















