如何在Vite中实现文件变更时运行自定义脚本?
在Vite中集成外部脚本处理静态内容
核心问题说明
你当前的代码存在两个关键问题:一是exec是异步方法,但Vite的transform钩子默认同步执行,导致回调里的code赋值无法生效;二是没有实现将文件内容通过标准输入(stdin)传递给外部脚本的逻辑。
解决方案
方法1:同步执行脚本(适合轻量处理)
使用child_process的execSync方法,直接将文件内容作为输入传给外部脚本,并捕获输出作为处理后的代码:
// vite.config.js import { execSync } from 'child_process'; export default { plugins: [ { name: "transform-html-with-script", transform(code, id) { if (id.endsWith(".html")) { try { // 将源内容通过stdin传入myscript.sh,获取处理后的输出 const processedCode = execSync('./myscript.sh', { input: code, encoding: 'utf8' // 确保输出为字符串格式 }); return { code: processedCode, map: null }; } catch (err) { console.error('外部脚本执行出错:', err.stderr); // 出错时返回原内容,避免构建中断 return { code, map: null }; } } return { code, map: null }; } } ] };
方法2:异步执行脚本(适合耗时处理)
如果脚本执行耗时较长,可将exec转为Promise异步调用,避免阻塞主线程:
// vite.config.js import { exec } from 'child_process'; import { promisify } from 'util'; // 把异步的exec转为Promise版本 const execPromise = promisify(exec); export default { plugins: [ { name: "transform-html-with-script", async transform(code, id) { if (id.endsWith(".html")) { try { const { stdout, stderr } = await execPromise('./myscript.sh', { input: code, encoding: 'utf8' }); if (stderr) console.warn('脚本执行警告:', stderr); return { code: stdout, map: null }; } catch (err) { console.error('外部脚本执行失败:', err.stderr); return { code, map: null }; } } return { code, map: null }; } } ] };
外部脚本示例(myscript.sh)
确保你的脚本可以读取stdin并输出处理后的内容,比如一个简单的模板替换脚本:
#!/bin/bash # 读取输入内容,将{{siteName}}替换为"我的静态站点" sed 's/{{siteName}}/我的静态站点/g'
注意事项
- 给脚本添加执行权限:
chmod +x myscript.sh - 若脚本依赖特定环境变量,可在
execSync/execPromise的env选项中配置 - 开发模式下,Vite会自动监听文件变更并触发transform,无需额外配置
内容的提问来源于stack exchange,提问作者Pithikos
相关产品推荐
相关产品推荐

