Vite插件在HTML注入动态脚本时标签被转义怎么办?

Mr-甜雅 阅读 24

我在用Vite写插件时想在HTML头部动态注入一个带有data-api-key的script标签,但发现内容被转义成文本了。比如用transformIndexHtml钩子处理时:


// 插件代码片段
export default ({ transformIndexHtml }) => {
  transformIndexHtml(html => {
    return html.replace('', 
      <script src="https://cdn.example.com/sdk.js" data-api-key="123"></script>
      </head>)
  })
}

构建后却变成了<script>标签的纯文本,而不是实际的DOM节点。试过用html.prettyPrint()和手动创建节点都没效果,这是Vite插件处理HTML节点时的特殊规则吗?

我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
Mc.雯婷
Mc.雯婷 Lv1
用unescape处理转义字符串,或者直接操作AST节点更稳妥

export default () => ({
transformIndexHtml(html) {
return html.replace('<script', '')
}
})
点赞 3
2026-02-07 08:21
IT人柯依
这个问题我也遇到过,确实是Vite在处理HTML时会自动转义特殊字符。用字符串替换的方式很容易踩坑,因为Vite内部会对HTML内容做序列化处理,你注入的内容会被当成纯文本处理。

正确的做法是利用transformIndexHtml钩子的第二个参数,它提供了一个叫server的对象,里面有个injectTag方法可以直接插入DOM节点。你可以这样改:

export default () => {
return {
name: 'inject-sdk',
transformIndexHtml(html, { server }) {
const scriptTag = {
tag: 'script',
attrs: {
src: 'https://cdn.example.com/sdk.js',
'data-api-key': '123'
},
injectTo: 'head'
};
server.injectTag(scriptTag);
return html;
}
};
};


我当时也是试了一圈字符串替换的方式,结果全被转义了。后来翻Vite的源码才发现这个方法,官方文档上还真没详细说明。用这种对象形式注入标签,才能绕过转义直接插入DOM节点。
点赞 4
2026-02-06 19:07