部署

了解如何将 Nuxt 应用部署到任何托管平台。

Nuxt 应用可以部署在 Node.js 服务器上、预渲染后托管在静态环境,或者部署到 Serverless 或边缘(CDN)环境。

如果你想查看支持 Nuxt 的云平台列表,参考托管平台章节。

Node.js 服务器

通过 Nitro 的 Node.js 服务器预设,部署到任何 Node 托管平台。

  • 未指定或自动检测时的默认输出格式
  • 只加载渲染请求所需的 chunk,实现最优冷启动速度
  • 适合将 Nuxt 应用部署到任何 Node.js 托管环境

入口文件

使用 Node 服务器预设运行 nuxt build 后,会生成一个启动即用 Node 服务器的入口文件。

NODE_ENV=production node .output/server/index.mjs

这会启动生产环境的 Nuxt 服务器,默认监听 3000 端口。

运行服务器时设置 NODE_ENV=production。有些依赖(尤其是 Vue Router)只有在设置了这个变量时才会去除开发警告,否则不匹配的路由可能会在日志里刷大量 [Vue Router warn]: No match found for location with path … 消息。

它支持以下运行时环境变量:

  • NITRO_PORT 或 PORT(默认 3000)
  • NITRO_HOST 或 HOST(默认 '0.0.0.0')
  • NITRO_SSL_CERT 和 NITRO_SSL_KEY — 两者都存在时,会以 HTTPS 模式启动服务器。绝大多数情况下,除了测试之外不应该使用这个功能,Nitro 服务器应该运行在 nginx 或 Cloudflare 等反向代理后面,由代理负责 SSL 终止。

同一构建在多路径下提供服务

普通子路径部署时,设置 app.baseURL 或 NUXT_APP_BASE_URL 环境变量。

如果反向代理故意在多个公开路径下暴露同一个渲染页面,Nuxt 可能会在水合时用服务端渲染的路径替换浏览器 URL。你可以在服务端插件中从 payload 里移除渲染路径来保留浏览器 URL:

export default defineNuxtPlugin((nuxtApp) => {
  delete nuxtApp.payload.path
})

仅当代理已经为每个公开路径处理资源和路由时才使用这个方案。没有了渲染路径,Nuxt 无法纠正请求 URL 和服务端渲染路由之间的真实不匹配。

PM2

PM2(Process Manager 2)是在你的服务器或 VM 上托管 Nuxt 应用的快速简单方案。

要使用 pm2,用 ecosystem.config.cjs 配置:

module.exports = {
  apps: [
    {
      name: 'NuxtAppName',
      port: '3000',
      exec_mode: 'cluster',
      instances: 'max',
      script: './.output/server/index.mjs',
      env: {
        NODE_ENV: 'production',
      },
    },
  ],
}

集群模式

你可以使用 NITRO_PRESET=node_cluster 来利用 Node.js cluster 模块的多进程性能。

默认采用轮询策略分发工作负载到 worker。

了解更多

静态托管

有两种方式将 Nuxt 应用部署到任何静态托管服务:

  • 静态站点生成(SSG):ssr: true 时在构建时预渲染应用的路由。(运行 nuxt generate 时的默认行为。)它还会生成 /200.html 和 /404.html 单页应用兜底页面,可以在客户端渲染动态路由或 404 错误(不过你可能需要在静态托管上配置)。参考什么是 200.html 和 404.html?。
  • 或者,你可以用 ssr: false 预渲染站点(静态单页应用)。这会生成 HTML 页面,其中 <div id="__nuxt"></div> 是空的,Vue 应用会在客户端渲染。这样会失去预渲染带来的很多 SEO 好处,建议用 <ClientOnly> 包裹无法服务端渲染的部分(如果有的话)。

预渲染的路由还会生成 _payload.json 文件,包含构建时捕获的数据,Nuxt 在客户端导航时复用。阅读更多关于 payload 提取。

静态兜底页面

Nuxt 可以为静态托管生成两个兜底页面:

  • 200.html 是单页应用兜底。当你想让客户端路由处理 URL 时,配置托管服务在不匹配的路由上返回它。
  • 404.html 是未找到兜底。配置托管服务在应该保持 404 状态的路由上返回它。

nuxt generate 和 nuxt build --prerender 会自动生成这些文件。如果你使用 nuxt build 配合路由规则预渲染部分路由,需要显式添加兜底页面:

export default defineNuxtConfig({
  routeRules: {
    '/200.html': { prerender: true },
  },
})

默认两个兜底页面都是空壳。设置 experimental.prerenderErrorPages 可以在构建时将你的 error.vue 服务端渲染到 404.html。

有些托管平台用 200.html,有些用 404.html,有些可以两者都配置。部署后检查你的托管平台的静态兜底或重写设置。

纯客户端渲染

如果你不想预渲染路由,另一种使用静态托管的方式是在 nuxt.config 中设置 ssr 属性为 false。nuxt generate 命令会输出 .output/public/index.html 入口和 JavaScript 包,就像传统的客户端 Vue.js 应用一样。

export default defineNuxtConfig({
  ssr: false,
})

托管平台

Nuxt 可以用极少的配置部署到多个云平台:

预设

除了 Node.js 服务器和静态托管,Nuxt 项目还可以用多个经过充分测试的预设进行部署,配置量极小。

你可以在 nuxt.config.ts 中显式设置预设:

// @errors: 2353
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server',
  },
})

...或者运行 nuxt build 时使用 NITRO_PRESET 环境变量:

NITRO_PRESET=node-server nuxt build

🔎 查看 Nitro 部署了解所有可用的部署预设和平台。

CDN 代理

大多数情况下,Nuxt 可以处理不是 Nuxt 自身生成的第三方内容。但有时这类内容可能导致问题,尤其是 Cloudflare 的"压缩和安全选项"。

因此,你应该确保在 Cloudflare 中取消勾选/禁用以下选项。否则,不必要的重渲染或水合错误可能影响你的生产应用。

  1. Speed > Settings > Content Optimization > 禁用 "Rocket Loader™"
  2. Security > Settings > 禁用 "Email Address Obfuscation"

设置完这些后,你可以确保 Cloudflare 不会向你的 Nuxt 应用注入可能导致副作用的脚本。

这些选项在 Cloudflare 控制台的位置有时会变,多找找看。