HTML代码规范拦截必须用html-validate等专用检查器并限定作用范围,因ESLint默认只解析JS语法,对纯HTML结构、可访问性属性、嵌套合法性等无校验能力,需通过git diff --cached动态提取变更文件来精准执行。

直接说结论:HTML 代码规范拦截不能只靠 eslint 或 prettier,必须用 html-validate 或 tidy 这类专用于 HTML 的检查器,并且要限制作用范围——只检查 git diff --cached 中的 .html/.vue/.jsx 文件,否则会误报、卡住提交。
为什么 ESLint 对 HTML 标签无效
eslint 默认只解析 JavaScript 语法,即使配合 eslint-plugin-vue 或 eslint-plugin-react,它对纯 HTML 文件(如 index.html)或模板中脱离 JS 上下文的结构(比如 Vue SFC 的 <template> 块里嵌套过深的属性)也缺乏语义校验能力。常见失效场景包括:
-
<img>缺少alt属性,eslint不报 -
<button>没有type,eslint不管 - aria-* 属性拼写错误(如
arai-label),eslint无法识别 - 嵌套非法(
<p><div></div></p>),eslint无感知
这些都属于 HTML 文档类型定义(DTD)和可访问性规范范畴,得交给 html-validate 这类工具。
怎么让 pre-commit 只检查改动的 HTML 文件
核心是避免全量扫描,否则每次提交都要遍历 src/ 下所有 HTML 模板,耗时且易因 node_modules 或构建产物干扰出错。正确做法是用 Git 命令动态提取暂存区变更:
立即学习“前端免费学习笔记(深入)”;
- 在
.husky/pre-commit脚本里,先运行git diff --cached --name-only --diff-filter=ACM | grep -E '\.(html|htm|vue|jsx)$' - 把结果传给
html-validate,例如:npx html-validate $(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(html|htm|vue|jsx)$' || echo "no-html") - 注意:如果没匹配到任何文件,命令会失败,所以加
|| echo "no-html"防止空输入中断流程 - 不要用 glob(如
**/*.html),它不感知 Git 状态,容易检查到未暂存或已删除的文件
html-validate 配置容易踩的坑
html-validate 默认规则偏严格,开箱即用常导致“明明能跑,就是不让提交”。关键调整点:
- 禁用
valid-id规则(React/Vue 中动态生成 id 很常见,硬校验反而阻碍开发) - 把
accessible-headings设为warn而非error,避免因文档片段缺失<h1>就阻断提交 - 对
.vue文件,需在配置里显式启用parser: "vue",否则<template>块会被当纯文本忽略 - 若项目用 Pug 或 JSX 写模板,必须换对应 parser(
pug或jsx),否则解析失败直接退出
配置示例(html-validate.json):
{
"rules": {
"valid-id": "off",
"accessible-headings": "warn"
},
"parsers": ["vue"],
"extends": ["html-validate:recommended"]
}和 lint-staged 协作时的路径陷阱
lint-staged 默认工作目录是项目根,但它的 glob 匹配不走 Git 索引,而是文件系统扫描——这意味着如果某次提交只改了 src/components/Button.vue,而 lint-staged 配置了 "*.vue": ["html-validate"],它仍会尝试检查 dist/Button.vue(如果存在)甚至 node_modules/some-lib/index.vue,引发权限错误或误报。
安全做法是不用 lint-staged 管 HTML,改用 husky 直接调用 shell 命令,或者在 lint-staged 配置里强制限定路径:
- 写成
"src/**/*.{html,vue,jsx}": ["html-validate"],而非"*.{html,vue,jsx}" - 确保
src/是你真实存放源码的目录,别依赖默认约定 - 如果项目有多个源码目录(如
src/和public/),得拆成两条规则分别指定
最麻烦但最稳的方式:放弃 lint-staged,在 .husky/pre-commit 里手写 git diff + xargs 调用,控制权完全在自己手里。



















