htmllint 是最轻量、最可控的 html 静态检查工具,基于 parse5 解析器精准验证结构与语义,支持细粒度规则配置、统一 json 输出,并可快速集成至 ci 与编辑器协同工作。

htmllint 是目前最轻量、最可控的 HTML 静态检查工具,它不依赖浏览器环境,也不做渲染模拟,只专注验证结构合法性与语义合规性。如果你需要在 CI 中快速拦截 <div> 嵌套 <code><p></p>、缺失 alt、重复 id 这类问题,别用 ESLint 插件或 Puppeteer 脚本——直接上 htmllint。
为什么 htmllint 比其他 HTML 检查方案更可靠
很多团队误用 eslint-plugin-html 或自写正则校验,结果漏掉嵌套错误、忽略自闭合标签合法性、甚至把合法的 <template></template> 当成错误标记。而 htmllint 基于真实 HTML5 解析器(parse5),能准确识别 void 元素、可选结束标签、属性布尔值语法等细节。
- 它不运行 JavaScript,不加载 CSS,避免因环境差异导致的误报
- 规则粒度细:比如
attr-name-style 可强制 data-xxx 小写连字符,attr-no-unsafe-char 拦截 URL 中未编码的空格
- 配置即代码:所有规则开关、例外路径都写在
.htmllintrc 里,无隐藏行为
- 输出格式统一:默认 JSON,方便后续用脚本提取行号、错误码、修复建议
常见报错及对应配置修正
运行 npx htmllint "**/*.html" 后常遇到以下三类高频问题,直接改配置比手动修代码更快:
Tag must be paired, missing:
→ 开启
"tag-pair": true,但注意它不处理模板字符串中的伪标签;若项目含大量 EJS/Handlebars,需用
"ignore": ["**/*.ejs"]
Attribute "class" not allowed on element "img" → 不是 bug,是 strict mode 下的语义限制;加 "attr-req-value": false 放宽对布尔属性的校验,或改用 "attr-allowed-values": { "img": ["src", "alt", "class"] }
Attribute "role" requires at least one of: aria-* attributes → 属于 WCAG 检查项;若临时跳过,加 "attr-required-for-role": false,但上线前必须补全 aria-label 或 aria-hidden
集成到 GitHub Actions 的最小可行配置
不要照搬 Super-Linter 的巨镜像方案——htmllint 单二进制即可运行,CI 中 2 秒内完成全量扫描:
name: HTML Lint
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install htmllint
run: npm install --global htmllint-cli
- name: Run htmllint
run: htmllint --config .htmllintrc --files "**/*.html"
关键点:--files 必须显式指定,否则默认只扫当前目录;.htmllintrc 文件必须存在且 UTF-8 编码,BOM 头会导致解析失败;如果仓库含大量静态生成 HTML(如 Jekyll 输出),记得在 ignore 列表中排除 _site/**。
与 SublimeLinter-html 的协同边界
编辑器内实时提示用 SublimeLinter-html(底层调用 tidy),CI 流水线用 htmllint,二者不是替代关系,而是分工:
-
SublimeLinter-html 擅长捕获未闭合标签、属性值引号缺失等“手抖型”错误,但对语义规则(如 img[alt])支持弱
-
htmllint 规则可精确到属性级,但无法感知编辑器上下文(比如光标所在行),不适合做实时高亮
- 两者配置文件不通用:
SublimeLinter 读 SublimeLinter.sublime-settings,htmllint 只认 .htmllintrc 或 --config 参数
真正容易被忽略的是:当 htmllint 报 Parse error: Unexpected token 时,往往不是 HTML 错误,而是文件混入了前端模板语法(如 {{ variable }})——这时必须用 ignore 排除对应路径,而不是强行关掉 parse 规则。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!