Vite构建Jinja2 SSG项目时JS文件未打包,求解决思路
问题:Vite + Jinja2构建时JS文件未被打包
使用Vite + Jinja2构建静态生成(SSG)落地页,开发阶段运行正常,但构建时base.html中引入的JavaScript文件完全缺失——Vite仅执行Jinja2解析并输出HTML结果,未对生成内容中的JS资源进行打包,最终仅输出index.html,且HTML内仍保留原路径的script标签。
项目结构
src ├── base.html (包含所有JS引入) ├── index.html (继承base) └── js ├── main.js └── mail.js
打包输出
dist └── index.html
打包后的index.html片段
<!doctype html> <html lang="en"> <head> <script type="module" src="./js/main.js"></script> <script type="module" src="./js/mail.js"></script> <!-- 其他页面内容 --> </head> </html>
插件代码(vite.config.js)
// 解析Jinja2语法的HTML文件 const htmlJinja2Parse = () => { return { name: 'html-transform', transformIndexHtml(html) { try { const modifiedHtml = execSync('python jinja2parse.py', { input: html, encoding: 'utf-8', }); return modifiedHtml; } catch (error) { console.error('执行Python脚本失败:', error); return html; // 出错时返回原HTML } }, } } export default defineConfig(({ mode }) => { return { // 其他配置项 build: { outDir: path.resolve(__dirname, 'dist'), emptyOutDir: true, rollupOptions: { input: { // 指定要构建的HTML文件 main: "./src/index.html", }, }, }, plugins: [ htmlJinja2Parse(), ] } });
原因分析
Vite的HTML资源扫描逻辑是先扫描入口HTML中的静态资源引用,再执行transformIndexHtml钩子。你的插件在钩子中替换了整个HTML内容,但此时Vite已经完成了资源扫描,无法识别Jinja2渲染后才出现的JS引用,因此不会打包这些JS文件。
解决方案
1. 手动声明构建依赖
在插件中添加buildStart钩子,显式告知Vite需要打包的JS文件,确保这些文件被纳入构建流程:
const htmlJinja2Parse = () => { return { name: 'html-transform', buildStart() { // 手动添加JS文件到构建依赖 this.addWatchFile('./src/js/main.js'); this.addWatchFile('./src/js/mail.js'); }, // 原有的transformIndexHtml逻辑不变 transformIndexHtml(html) { try { const modifiedHtml = execSync('python jinja2parse.py', { input: html, encoding: 'utf-8', }); return modifiedHtml; } catch (error) { console.error('执行Python脚本失败:', error); return html; } }, } }
2. 让Vite重新识别动态生成的资源
修改transformIndexHtml的返回格式,返回包含html和tags的对象,让Vite重新扫描并处理新的资源引用:
transformIndexHtml(html) { try { const modifiedHtml = execSync('python jinja2parse.py', { input: html, encoding: 'utf-8', }); // 提取渲染后的script标签 const tags = []; const scriptRegex = /<script type="module" src="([^"]+)"><\/script>/g; let match; while ((match = scriptRegex.exec(modifiedHtml)) !== null) { tags.push({ tag: 'script', attrs: { type: 'module', src: match[1] }, injectTo: 'head' }); } // 返回处理后的HTML(移除原script标签)和新的资源标签 return { html: modifiedHtml.replace(scriptRegex, ''), tags: tags }; } catch (error) { console.error('执行Python脚本失败:', error); return html; } }
3. 改用官方SSG工具
如果项目复杂度较高,推荐使用vite-plugin-ssg,它对模板引擎的动态资源处理支持更完善,能自动识别渲染后的资源引用并完成打包。
内容的提问来源于stack exchange,提问作者Pithikos
相关产品推荐
相关产品推荐

