Vue

Nuxt 3 预渲染与环境变量问题总结

Nuxt 3 预渲染与环境变量问题总结

问题描述

在首页 (/) 使用预渲染 (prerender: true) 时,页面需要调用 API 接口,而 API 的 baseURL 是通过 runtimeConfig 从环境变量中获取的。打包 Docker 镜像后运行,报错找不到 output 目录下的 index.mjs 文件。

根本原因

预渲染(Prerender)发生在构建阶段,此时:

  1. 环境变量尚未注入(Docker 运行时才会注入)
  2. runtimeConfig.public.API_BASE_URL 的值为空字符串 ''
  3. API 调用失败,导致预渲染过程中断
  4. 最终 index.mjs 文件未能正确生成
// nuxt.config.ts 原配置
runtimeConfig: {
  public: {
    API_BASE_URL: ''  // 构建时为空,运行时才从 env 注入
  }
},

routeRules: {
  '/': { prerender: true }  // ❌ 预渲染时拿不到环境变量
}

预渲染 vs 运行时渲染

特性预渲染 (Prerender)ISR / SSR
执行时机构建阶段运行阶段
环境变量可用性❌ 不可用✅ 可用
适用场景纯静态页面动态数据页面

解决方案

将预渲染改为 ISR(增量静态再生)SSR

// nuxt.config.ts 修改后
routeRules: {
  // '/': { prerender: true },  // ❌ 注释掉
  '/': { isr: 60 * 60 * 1 }     // ✅ 使用 ISR,缓存 1 小时
}

ISR 优势

  • 运行时渲染:首次请求时在服务端渲染,可以获取环境变量
  • 缓存机制:渲染结果缓存指定时间(如 1 小时),减少服务器压力
  • 自动更新:缓存过期后自动重新渲染,保证数据新鲜度

最佳实践建议

  1. 需要调用 API 的页面:使用 ISR 或 SSR,避免使用预渲染
  2. 纯静态页面:可以使用预渲染,如关于页面、隐私政策等
  3. 环境变量敏感操作:确保在运行时执行,而非构建时

相关配置参考

routeRules: {
  // 预渲染 - 仅适用于不依赖环境变量的静态页面
  '/about': { prerender: true },
  
  // ISR - 适用于需要环境变量且数据更新不频繁的页面
  '/': { isr: 3600 },           // 缓存 1 小时
  '/products': { isr: 1800 },   // 缓存 30 分钟
  
  // SSR - 适用于数据实时性要求高的页面
  '/dashboard': { ssr: true }
}