You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:27:45