新项目初始化时必须配htmlhint,因为它能将语义化、可访问性、seo等团队共识固化为可执行规则,写入第一天的.htmlhintrc;默认规则不启用alt-require等关键项,需手动开启attr-lowercase、attr-no-duplication、attr-req-alt、head-script-disabled、id-unique等高优先级规则,避免后期修复成本指数上升。

新项目初始化时为什么必须配 HTMLHint 而不是等出问题再补
因为 HTML 问题在开发早期几乎不报错,但会悄悄污染整个渲染链路——比如 <div> 忘闭合,浏览器自动容错修复,开发者根本看不到异常,可一旦接入 SSR 或静态站点生成器(如 Astro),就会直接报错中断构建;又比如 <code>alt 缺失,在本地预览毫无感知,上线后却触发 Lighthouse 可访问性评分暴跌。这些问题越晚介入,修复成本越高,且常需回溯多个模板文件。
HTMLHint 的价值不在“查错”,而在“设边界”:它把团队对语义化、可访问性、SEO 友好的共识,固化成可执行的规则,写进项目第一天的 .htmlhintrc 里,而不是靠 Code Review 临时提醒。
- 必须在
package.json的precommit或prebuild钩子里集成htmlhint,否则等于没配 - 不要用默认规则集——默认不校验
img[alt]、meta[name]等关键项,得手动开 - 若项目用 Astro 或 Vue SFC,需额外配置
htmlhint的htmlhint-loader或eslint-plugin-html插件,否则只扫纯.html文件
哪些 HTMLHint 规则该在第一天就强制启用
新手常误以为“规则越多越好”,结果配置完发现 200+ 报错,直接放弃。真正要优先启用的,是那些一旦违反就无法被运行时掩盖、且修复成本随迭代指数上升的规则。
-
attr-lowercase:强制属性名小写(class而非CLASS),避免和 JSX/TSX 混用时大小写冲突 -
attr-no-duplication:禁止重复属性(如class="a" class="b"),这类错误在 Vue/Astro 中会覆盖前值,极难调试 -
attr-req-alt:所有<img>必须含alt,空值允许但需显式写alt="" -
head-script-disabled:禁用里内联<script></script>,防止阻塞渲染且与现代打包逻辑冲突 -
id-unique:确保全局id唯一,否则 SSR hydration 时 React/Vue 会丢状态
如何让 HTMLHint 规则不变成新人的阻碍
规则太严,新人提交 PR 直接被 CI 拦住,容易引发抵触;太松,又形同虚设。关键在于把“检查时机”和“修复引导”做对。
- 本地开发时用 VS Code 插件
HTMLHint实时标红,但不阻止保存——让问题可见但不打断流程 - CI 中只对
src/pages/**/*.html和src/layouts/*.html运行严格检查,忽略node_modules和生成目录 - 在
.htmlhintrc里为每条启用规则加注释,说明“为什么这条不能关”,例如:"attr-req-alt": ["error", {"allowEmpty": true}] // 无障碍基础,空 alt 表示装饰性图片 - 把常见报错映射到具体修复动作,比如
attr-lowercase报错时,直接提示“请运行npx htmlhint --fix .自动修正”
HTMLHint 和其他工具怎么分工不打架
很多人把 ESLint、Prettier、HTMLHint 全堆一起,结果格式化脚本跑三遍,class="a b" 被 Prettier 拆成多行,又被 HTMLHint 报“属性换行不合规”。根源在于没划清职责边界。
- HTMLHint 只管语义和结构合规性(是否闭合、是否缺 alt、是否用语义标签),不管缩进或引号风格
- Prettier 负责格式统一(单双引号、空格、换行),但 必须关闭它对 HTML 的标签闭合和属性排序处理,否则和 HTMLHint 冲突
- ESLint 不处理纯 HTML 文件,只管 JS/TS 逻辑;若用 Astro,需通过
eslint-plugin-astro检查组件内嵌 HTML - 若项目含 Markdown 渲染(如 Astro 的
.md页面),需单独配remark-lint,HTMLHint 对它无效
真正卡住技术债蔓延的,从来不是某一行代码写得不够漂亮,而是第一份 HTML 模板生成时,有没有人明确说:“这个 <header></header> 里必须有 role="banner",现在就加,别等 QA 提 bug。”











