Nuxt 3 生成部署
Nuxt 应用可以部署到具有 Node.js 环境的服务器,也可以将经过 pre-rendered 预渲染的结果部署到 static 静态网页托管平台,或 serverless 和 edge(CDN)环境
参考
本文主要参考 Nuxt 官方文档 Deployment 这一章节。
Nuxt 使用的后端服务器引擎是 Nitro,也可以查看Nitro 官方文档了解如何配置 Nitro 将 Nuxt 应用部署到服务器。
此外 Nuxt 还专门针对一些主流的云托管平台给出具体的操作指南
如果需要修改 runtime 运行环境参数,可以采用以下任一方法:
- 在终端运行代码时提供 environment variable 环境变量(特别适用于依赖 CI/CD 的部署环境)bash
# 使用 NITRO_PRESET 作为环境变量 NITRO_PRESET=aws-lambda nitro build
- 设置
nitro.config.ts
配置文件nitro.config.tstsimport { defineNitroConfig } from "nitropack"; export default defineNitroConfig({ preset: 'node-server' })
渲染模式
网站需要在浏览器上显示出来,所以需要将 Vue 的组件(代码)解析为 HTML、CSS 和 JavaScript,该过程称为渲染 rendering。
Nuxt 提供了丰富的渲染模式,以适用多种应用场景,可以在 Nuxt 的配置文件中进行渲染模式的配置和切换。
export default defineNuxtConfig({
ssr: true // 默认开启服务器渲染,即采用「客户端-服务器渲染模式」 universal rendering
// 如果设置为 false,则表示采用客户端渲染
})
Nuxt 2 支持在客户端渲染 client-side only 和客户端-服务器两者结合的渲染 universal(由于代码可以在服务器和客户端运行,所以称为「通用」渲染模式)两种模式:
- 客户端渲染模式 client-side only rendering
浏览器/客户端下载 HTML 模板和 JS 脚本并执行,再在客户端渲染出完整的网页应用。一般适用于需要处理较多用户交互操作,以及不太需要 SEO 优化的网站。
由于 Nuxt 是采用 Vue 作为前端框架,Vue 本身就是使用这种模式来构建 SPA 网站的,所以这种模式在 Nuxt 2 项目中可做到开箱即用。 - 通用渲染模式 universal rendering
当浏览器向服务器发出请求时,服务器会返回一个网站的 HTML 文档(可以是预先生成并缓存在服务器中,或接到客户端请求后再生成),这和传统的服务器端渲染 server-side(使用 PHP 或 Ruby 的传统服务器)类似。这种模式可以有较好的 SEO 优化,一般适用于展现内容为主的网站,如博客、商务网站,Nuxt 默认采用这种模式。
此外该模式还保留了一定程度的客户端渲染,以便让页面可以处理用户的交互,使得这种渲染模式适用场景更灵活。
当下载完从服务端发过来是 HTML 后,Nuxt 会在后台加载运行从服务端发来的 JavaScript 代码,然后客户端会再次解析网页,并使用 Vue 接管和控制网页,这样就可以处理用户的交互
💡 因为使用了服务端进行完整的 HTML,不必依赖客户端,不受设备、浏览器等限制,所以称为通用渲染 ❓
💡 将静态网页变成可交互的过程称为 Hydration说明
通用渲染模式 universal rendering 是 Nuxt 所采用的默认渲染模式。
可以通过 Nuxt 的配置文件 📄
nuxt.config.ts
来调整渲染模式nuxt.config.tstsexport default defineNuxtConfig({ // ssr 全称为 server side rendering 服务端渲染 // 设置为 false,则表示不会在服务端进行渲染 // 即网址只采用客户端渲染 ssr: false })
Nuxt 3 还提供了一种更先进的渲染模式——混合渲染 hybrid。可以控制每一个路由(页面)的缓存规则,以设定服务器应该如何响应客户端发出的每一条 URL 请求。由于通用渲染一般采用 Node.js 环境,Nuxt 3 还提供一种渲染模式——边缘渲染 edge-side,可以利用 CDN 的 workers 进行渲染,以减低网络的延迟。
- 混合渲染模式 hybrid rendering
可以为**每个的路由(页面)**设置不同的渲染和缓存规则,有的页面可能更适合在服务器渲染,有的页面可能更适合在客户端渲染。
例如在有访问权限约束的网站,对于普通的页面可以先在服务器统一生成(只执行一次渲染),而对于会员专属的页面则应该采用客户端渲染(类似一个动态的网页应用,这些页面应该按需生成)。
更多信息可以查看社区的讨论
Nuxt 3 可以在文件 📄nuxt.config.ts
的属性routeRules
中为路由配置规则,以设置其渲染和缓存模式,Nuxt 后端服务器会自动注册相应的 middleware 中间件,使用 nitro caching layer 来处理这些路由。
以下是一系列支持配置的路由规则:- 属性
redirect
:字符串。为路由定义一个服务端的路由重定向 - 属性
ssr
和属性static
以及属性swr
:布尔值。为路由设置不同的渲染模式。ssr: true
采用服务端渲染模式static: true
采用静态页面渲染模式swr: true
采用
说明
- Static 渲染模式:在构建时 build 生成静态 HTML 文件。
这种渲染方式适用于静态内容不会经常变化的网站,如博客、公司官网等。 - SWR 渲染模式:全称为 Stale While Revalidate 使用过期数据但同时进行重新请求,即在客户端请求数据时,先从缓存中读取数据同时发起请求,最后获取最新的数据,并在获取到数据后更新缓存。
它会先使用旧数据/缓存显示到页面上,不让用户等待,同时去发起请求获取最新的数据,如果数据有更新,则用返回的新数据刷新页面 UI。
这种渲染方式可以提高 UX 用户体验,相当于兼容了 static 的快速响应性和 ssr 的实时性,适用于需要频繁更新数据的网站,如社交网站、电商网站等。 - SSR 渲染模式:全称为 Server Side Rendering 服务器端渲染,该模式会在服务器端生成 HTML 文件,并在客户端进行交互。
这种渲染方式适用于需要 SEO 优化的网站,如新闻、论坛等。
- 属性
cors
:布尔值。路由是否自动添加 cors headers
也可以通过属性headers
来覆盖它 - 属性
headers
:字符串。为路由/页面添加特定的 headers,例如为页面添加 assets
nuxt.config.tsts// example export default defineNuxtConfig({ routeRules: { // Static page generated on-demand, revalidates in background '/blog/**': { swr: true }, // Static page generated on-demand once '/articles/**': { static: true }, // Set custom headers matching paths '/_nuxt/**': { headers: { 'cache-control': 's-maxage=0' } }, // Render these routes with SPA '/admin/**': { ssr: false }, // Add cors headers '/api/v1/**': { cors: true }, // Add redirect headers '/old-page': { redirect: '/new-page' }, '/old-page2': { redirect: { to: '/new-page', statusCode: 302 } } } })
提示
目前 Nuxt 3 自动支持 Netlify 和 Vercel 两个平台的原生路由规则 ❓
目前在 Netlify 平台上采用 swr 渲染模式支持完全增量静态生成
- 属性
- 边缘渲染 edge-side rendering
服务端渲染 server side rendering 和通用渲染模式 universal rendering 一般只能在运行着 Node.js 环境的后端中使用,而 Nuxt 3 采用一个全新的服务端渲染引擎 Nitro,让适用场景更进一步
它支持多种环境,除了浏览器、Node.js,还可以在 CDN edge workers 中渲染 Nuxt 应用,让用户访问网站时所感受到网络延迟更低。
另外 Nuxt 3 现在也已经支持静态页面生成 Full Static site generation,通过这种渲染模式生成的网页可以部署到各种静态页面托管平台,如 Vercel、GitHub Pages、Cloudflare Pages 等。
Node 服务器
在终端运行 nuxt build
会生成一个结果文件夹 📁 .output
,其中 📄 .output/server/index.mjs
就是服务器的入口文件
将其部署到具有 Node.js 环境的服务器中,并执行以下代码就可以启动应用
node .output/server/index.mjs
# 输出(默认使用 3000 端口)
# Listening on http://localhost:3000
可以通过以下的一些环境变量设置应用 runtime 运行时的参数:
NITRO_PORT
或PROT
设置端口(默认为3000
)NITRO_HOST
或HOST
设置主机地址NITRO_SSL_CERT
或NITRO_SSL_KEY
加密方式(除了用于测试,一般不推荐设置)
使用 PM2
如果需要使用 PM2 可以设置 ecosystem.config.js
配置文件
module.exports = {
apps: [
{
name: 'NuxtAppName',
port: '3000',
exec_mode: 'cluster',
instances: 'max',
script: './.output/server/index.mjs'
}
]
}
静态网页托管
使用以下命令,会在 📁 .output/public
目录中一系列文件,它们可以直接部署到静态网页托管平台上
npx nuxi generate
说明
Nuxt 的爬虫机器人 crawler 会根据路由生成相应的 HTML 文件和 payload 文件(一堆 JS 文件,包含页面相应的数据),
生成静态网页有的两种渲染模式可选:
- 在配置文件中设置
ssr: true
,就会采用服务端的方式(nuxi generate
命令所采用的默认渲染模式),将各路由进行预渲染 pre-render 生成多个静态页面
而且它会自动生成/200.html
和/404.html
作为 fallback 回退页面以处理动态路由和错误的路由 - 在配置文件设置
ssr: false
,那么在终端执行nuxi build
时会生成一个静态的 SPA 单页面应用
它会生成一个「空」的 HTML 页面.output/public/index.html
作为入口(其核心内容仅有<div id="__nuxt"></div>
元素),Vue 会在客户端再 mounted 到这个页面上
采用 ssr: false
方式适用于页面无法在服务端生成的场景,例如一些代码需要依赖浏览器的 API,但是这种方式就无法利用页面预渲染的诸多好处,例如加快页面的加载速度、更好的 SEO 等
所以推荐采用 ssr: true
方式,对于无法在服务端渲染的部分代码,则使用 Nuxt 内置的 <ClientOnly>
组件进行 wrap 封装,这样应用剩余的部分都可以先进行预渲染,生成静态的页面
相应地,如果应用的大部分页面都无法在服务端生成,需要采用 ssr: false
模式时,也可以在配置文件 nuxt.config.ts
为特定的一些路由设置预渲染模式,以便对其中一两个页面进行优化
defineNuxtConfig({
nitro: {
prerender: {
routes: ['/user/1', '/user/2']
}
}
})