Vite自定义插件transformIndexHtml钩子构建时失效问题求助
问题原因及解决方案
核心问题出在你的打包入口配置上:你在rollupOptions.input里指定了JS文件(entry.ts)作为打包入口,而非index.html。
Vite的transformIndexHtml钩子仅在以HTML文件为打包入口时才会触发:
- 开发模式下,Vite默认以项目根目录/
public目录的index.html为入口,所以钩子能正常生效; - 构建模式下,若入口是JS文件,Vite只会直接复制
public目录的index.html到dist,不会经过transformIndexHtml的处理流程,导致钩子不触发。
解决方法(二选一)
方法一:改用HTML作为打包入口(推荐,符合Vite设计理念)
修改vite.config.ts中的rollupOptions.input,指向你的index.html文件:
rollupOptions: { input: { app: path.resolve(__dirname, 'public/index.html'), // 或根目录的index.html,根据实际路径调整 }, // 其他配置保持不变... }
同时确保index.html里正确引入你的入口JS:
<script type="module" src="/src/scripts/entry.ts"></script>
这样构建时Vite会以HTML为入口处理,transformIndexHtml钩子就会正常触发。
方法二:保留JS入口,手动处理HTML(适合特殊场景)
如果必须以JS为入口,可以改用Rollup的writeBundle钩子,在打包完成后手动读取并修改index.html:
修改你的插件代码:
return { name: 'html-build-plugin', apply: 'build', async writeBundle(outputOpts) { const fs = await import('fs/promises'); const path = await import('path'); // 读取public中的原始HTML const sourcePath = path.resolve(__dirname, 'public/index.html'); // 目标dist中的HTML路径 const targetPath = path.resolve(outputOpts.dir || 'dist', 'index.html'); let htmlContent = await fs.readFile(sourcePath, 'utf8'); // 执行你的替换逻辑 htmlContent = htmlContent.replace('<title>', '<title>aaa:'); // 写入dist目录 await fs.writeFile(targetPath, htmlContent); } };
内容的提问来源于stack exchange,提问作者Furman
相关产品推荐
相关产品推荐

