@babel/parser 不能解析 HTML,因其仅支持 JS/TS 语法,遇 等标签即报 SyntaxError: Unexpected token

为什么不能用 @babel/parser 解析 HTML?
直接拿 JS 解析器去处理 HTML 字符串,@babel/parser 会立刻报错:SyntaxError: Unexpected token 。它只认 JS/TS 语法,遇到 <code><div> 就卡死。HTML 必须用专用解析器——比如 <code>parse5(完整 HTML5 支持)、htmlparser2(快但不校验嵌套)或轻量级的 simple-html-parser。
常见错误是试图“绕过”这个限制:比如先正则提取 script 标签内容再丢给 Babel。这不可靠——JS 代码可能被注释包裹、字符串里含 、或混着 JSX/Vue 模板语法。必须先剥离模板逻辑,再分语言交给对应解析器。
parse5 解析后拿到的 AST 长什么样?
parse5.parse() 返回的是 Document 节点,不是 ESTree 风格的树,结构更贴近 DOM:有 tagName、attrs(数组,每个元素是 { key: string, value: string | null })、childNodes(混着 Element 和 Text)、isSelfClosing 等字段。
容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
- 把
attrs当成对象直接attr['class'] = 'new',实际得重构造整个数组 - 遍历
childNodes时没判断node.nodeType === ELEMENT_NODE,对文本节点调用getAttribute直接报错 - 忽略
isSelfClosing,把<img alt="自动化AST分析在HTML代码质量检测中的应用" >改成<img alt="自动化AST分析在HTML代码质量检测中的应用" >,序列化后 HTML 就错了
怎么安全地批量修改 HTML 标签或属性?
别用正则替换。比如把所有 <button></button> 替成 <div role="button">,正则搞不定嵌套、引号转义、注释干扰、属性换行等边界情况。
<p>正确做法是 AST 遍历 + 节点重建:</p>
<ul>
<li>用 <code>parse5.treeAdapter.map 或 htmlparser2 的 DomHandler 构建可写树,避免只读 AST
t.element({ tagName: 'div', attrs: [...oldAttrs, { key: 'role', value: 'button' }] }),不拼字符串class 属性要小心:原值是 "a b",加 c 应得 "a b c",建议用 classList 工具或正则安全提取<input>、<img alt="自动化AST分析在HTML代码质量检测中的应用" >)替换后必须显式设 isSelfClosing: true
检测 HTML 坏味道时,AST 比字符串匹配强在哪?
字符串匹配只能找固定模式,比如查有没有 onclick=。AST 能理解上下文:比如识别出某个 <div> 实际被用作按钮(含 <code>tabindex、role="button"、绑定 click 事件),但没加 aria-pressed 或键盘支持——这种语义级缺陷,正则根本看不到。
另一个典型是空链接:<a href="#"></a>。字符串能抓到,但 AST 可进一步判断它是否在 click 处理器里调用了 preventDefault(),或者是否包裹了 button 元素。没有上下文的“告警”只会制造噪音。
真正难的不是解析,是定义规则时如何平衡精确性与实用性——比如“所有图片必须有 alt”看似简单,但 CMS 生成的占位图、SVG 图标、装饰性 <img alt="自动化AST分析在HTML代码质量检测中的应用" > 是否该豁免?这些得靠 AST 提供的节点关系(父元素、兄弟节点、属性组合)来判断,而不是硬编码关键词。



















