内容提要
本文介绍基于 Vite 的 Vue 3 预渲染方案:在 index.html 中添加资源注入注释,将入口拆分为客户端与服务端两个文件,路由自动读取 views 目录生成,并为各页面配置 SEO 标题、描述与关键词。通过 prerender 脚本按路由生成静态 HTML,可部署 dist/static,并支持一次性构建所有平台。文中还指出水合节点不匹配警告可忽略,路由跳转需用 Suspense 包裹 router-view。
延伸解读
预渲染与SSG的取舍
文章提到预渲染与静态生成器接近,并推荐了vite-ssg和vite-plugin-pages。但本文选择基于Vite原生支持自行实现,适合需要轻量定制、不想引入额外依赖的团队。这种方案更灵活,但需要手动处理入口拆分、路由生成和SEO配置,适合对构建流程有控制需求的开发者。
入口拆分的必要性
将原来的main.ts拆分为entry-client.ts和entry-server.ts是预渲染的关键步骤。客户端入口负责浏览器端激活,服务端入口用于生成静态HTML。这种拆分让同一套代码既能用于客户端渲染,也能在构建时生成预渲染页面,避免了为预渲染单独维护一套代码。
SEO配置的集中管理
文章将每个页面的标题、描述和关键词配置放在src/router目录下统一管理,并根据路由路径匹配写入。这种做法便于维护和扩展,尤其适合页面数量较多的项目。但需要注意,这些配置是静态的,如果页面内容需要动态SEO信息,可能需要更复杂的方案。
常见问题的处理建议
水合节点不匹配警告通常可以忽略,但路由跳转报错需要改用Suspense包裹router-view。这说明预渲染后客户端激活阶段可能存在细微差异,开发者应关注控制台警告,但不必过度反应。对于路由跳转问题,按照文章给出的模板调整即可解决。
Q&A
Vue3项目用Vite做预渲染,index.html里需要加哪些注释?
需要在index.html中添加至少两条资源注入位置的注释:<!--preload-links-->(预加载资源)和<!--app-html-->(页面内容)。此外,为了SEO优化,还可以选择性添加<!--title-->、<!--description-->和<!--keywords-->注释,用于写入标题、描述和关键词。
Vite预渲染时入口文件要怎么改造?
需要将原来的main.ts拆分为两个入口文件:entry-client.ts作为客户端入口,entry-server.ts作为服务端入口。原来的main.ts只作为入口函数导出,供客户端和服务端启动时引用。
预渲染时路由还需要手动配置吗?
不需要手动配置路由结构。改造后,路由会自动读取src/views目录下的路由组件来生成页面路由,简化了路由配置工作。
如何为每个页面配置SEO的标题、描述和关键词?
在src/router目录下管理SEO配置,以每个页面的相对路径为键,配置对应的title、description和keywords。例如:export default [{ url: '/', title: '首页', description: '这是首页', keywords: ['关键词1', '关键词2'] }]。预渲染时会根据路由路径写入对应的TKD信息。
预渲染脚本怎么用?生成的文件如何部署?
运行npm run generate执行预渲染脚本(scripts/prerender.ts),它会按照路由目录结构生成静态HTML文件。生成的文件位于dist/static,可以直接作为静态站点部署。另外,npm run build可以一次性编译所有平台(Client/Server/Static)。
预渲染后控制台报水合节点不匹配警告怎么办?
水合节点不匹配警告(如Hydration node mismatch)通常可以忽略,它来自hydration.ts,不影响功能。如果希望深入了解,可以参考相关文章解决水合错误。
预渲染后路由跳转报错怎么解决?
路由跳转报错(Unhandled error during execution of scheduler flush)需要使用<Suspense>标签包裹路由视图。示例:<router-view v-slot="{ Component }"><Suspense><div><component :is="Component" /></div></Suspense></router-view>。