PostHTML插件必须返回修改后的树对象,否则转换无效;常见错误包括漏返node、外部return字符串、未判空content、忽略children类型及嵌套递归;Webpack中需设sync: true;转义内容须先解码再处理;跨节点逻辑需外部维护上下文。

PostHTML插件必须返回修改后的树对象,否则转换无效
常见错误是插件函数里只做 console.log 或直接 return 原始字符串。PostHTML 的处理流程依赖 AST(PostHTMLTree)的可变引用,插件必须显式操作 node 或调用 tree.match() 并返回新节点,否则后续链式调用会丢失变更。
正确写法示例:
posthtml().use((tree) => {
tree.match({ tag: 'my-button' }, (node) => {
node.tag = 'button';
node.attrs.class = (node.attrs.class || '') + ' custom-btn';
return node; // 必须返回修改后的 node
});
})
- 漏掉
return node→ 标签不变,且无报错 - 在
tree.match()外部直接return 'xxx'→ 整个 HTML 被替换成该字符串,破坏结构 - 使用
node.content时未判断是否为数组(空标签 content 是undefined)→ 运行时报Cannot read property 'map' of undefined
自定义标签嵌套逻辑需手动处理 children,不能只改 tag 名
比如把 <tabs><tab title="A">Content</tab></tabs> 转成语义化结构,仅改 tag 不够——<tab> 子节点需要提升到 <tabs> 下作为 <div role="tabpanel">,同时生成对应 <button role="tab">。这要求你遍历 node.children,提取属性、重组节点树。
关键点:
立即学习“前端免费学习笔记(深入)”;
-
node.children是数组,但可能含文本节点(type: 'text')、注释(type: 'comment'),需过滤或保留 - 若子节点中存在同名自定义标签(如嵌套
<tab>),要递归处理或加深度限制,避免无限循环 - 添加新节点时用
{ tag: 'div', attrs: {}, content: [...] }格式,不要用字符串拼接,否则逃逸逻辑失效
Webpack 中 html-loader 的 postprocessor 同步模式必须设 sync: true
在 Webpack 配置里调用 posthtml().process(content, { sync: true }) 是硬性要求。异步模式(默认)会返回 Promise,而 html-loader 的 postprocessor 函数必须同步返回字符串,否则构建卡住或报错 TypeError: Cannot read property 'html' of undefined。
典型错误配置:
// ❌ 错误:没设 sync,process 返回 Promise
options: {
postprocessor: (content) => {
return posthtml().use(myPlugin()).process(content).then(r => r.html);
}
}
正确写法:
// ✅ 正确:显式声明 sync: true
options: {
postprocessor: (content) => {
return posthtml()
.use(myPlugin())
.process(content, { sync: true })
.html;
}
}
转义与非转义内容混用时,插件内需跳过已转义的实体
如果原始 HTML 里已有 或 <code><,而你的插件又对文本内容做正则替换(比如统一将 foo 替成 bar),就可能把 <div>> 错改成 <code><bar>>,导致页面显示 <code><bar> 而不是 <div>。



















