HTMLHint默认将自定义标签(如<my-button>)视为unknown-tag错误,需在.htmlhintrc中显式声明"tags": ["my-button", "my-input"]或通配data-*属性;不支持自动识别动态注册元素。

怎么让 HTMLHint 识别自定义标签(如 )而不报错
默认情况下,HTMLHint 会把未知标签当作语法错误,比如 <my-button> 直接触发 unknown-tag 规则报错。这不是 bug,而是设计使然——它只认标准 HTML 元素。
解决方法是显式声明允许的自定义标签,在配置文件中扩展 tags 列表:
- 在
.htmlhintrc中添加:"tags": ["my-button", "my-input", "data-*"] -
data-*是通配写法,匹配所有 data-* 属性,但不匹配自定义元素;自定义元素必须逐个列出 - 如果用 Web Components(如 Lit、Stencil),建议把所有已注册的
customElements.define()名称都加进去 - 注意:HTMLHint 不解析 JS,所以它无法自动发现动态注册的元素,全靠手动维护列表
如何用自定义规则强制校验 <my-card> 必须带 title 属性
内置规则管不了自定义标签的属性约束,必须写自定义 rule。核心是监听 starttag 事件,检查 tagName 和属性存在性:
module.exports = function(HTMLHint) {
HTMLHint.addRule({
id: 'my-card-title-required',
description: 'my-card must have title attribute',
init: function(parser, reporter) {
parser.on('starttag', function(event) {
if (event.tagName === 'my-card' && !event.attrs.some(a => a.name === 'title')) {
reporter.error(
'my-card requires title attribute',
event.line,
event.col,
this
);
}
});
}
});
};关键点:
立即学习“前端免费学习笔记(深入)”;
- 不要依赖
event.attrs的顺序或大小写——a.name === 'title'是安全写法 - 若允许
Title或TITLE,需统一转小写再比:a.name.toLowerCase() === 'title' - 该规则不会检查
title是否为空字符串,如需进一步校验,得加a.value && a.value.trim() - 规则加载方式:通过
--rulesdir ./rules命令行参数或配置项"rulesdir": ["./rules"]
为什么 htmllint 对自定义元素的支持比 HTMLHint 更灵活
htmllint 默认不报未知标签错,它把标签合法性交给解析器层(如 parse5)处理,而 HTMLHint 是硬编码白名单校验。
这意味着:
- htmllint 能直接跑过
<my-dialog open>,只要结构合法,不额外报unknown-tag - 但它也不校验自定义属性,比如
<my-input required>中的required是否被组件支持——这得靠你写 rule - htmllint 的
attr-req规则支持正则匹配标签名:"attr-req": { "my-.*": ["title"] },比 HTMLHint 的静态列表更适配组件库演进 - 缺点:htmllint 没有 HTMLHint 那么多开箱即用的语义化规则(如
head-title-require),得自己补
自定义标签参与原生表单验证时,reportValidity() 为何失效
原生 reportValidity() 只遍历 form.elements,而自定义元素不在其中——哪怕它内部有 <input>,浏览器也视其为“黑盒”。
真实可行的做法只有两种:
- 在自定义元素内部调用子
<input>.reportValidity(),并在setCustomValidity()后触发dispatchEvent(new Event('invalid', { bubbles: true }))向外冒泡 - 重写表单提交逻辑:
form.addEventListener('submit', e => { e.preventDefault(); if (!validateMyComponents()) return; form.submit(); }) - 别指望
novalidate加到自定义标签上生效——它只对<form>有效 - Vue/React 渲染的自定义组件,
form.reset()完全不重置它们的状态,必须手动同步
最易忽略的一点:自定义元素的 validity 状态无法被 :valid/:invalid CSS 伪类捕获,样式反馈只能靠 JS 手动加 class。



















