返回

在现有 Vue3 + Vite + TypeScript 项目中使用 Vike 实现静态预渲染(SSG)

原创
admin的头像admin·发布于 2025-07-16 12:31·阅读 252

背景简介

在一个已经运行良好的 Vue3 + Vite + TypeScript 项目中,为了满足 SEO 优化需求,需要将少量关键页面预渲染为静态 HTML。相比于服务端渲染(SSR),静态生成(SSG)对项目结构简单、页面数量有限的场景更加轻量。本文示范如何基于 Vite 插件 Vike(原 vite‑plugin‑ssr)快速为现有项目添加静态预渲染支持。


file

1. 安装并配置 Vike

  1. 使用 npm 或 yarn 安装插件:
    bash 复制代码
    npm install vike --save-dev
    # 或
    yarn add vike --dev
复制代码
2. 在 `vite.config.ts` 中引入并启用预渲染:

   ```ts
   import { defineConfig } from 'vite'
   import vue from '@vitejs/plugin-vue'
   import vike from 'vike/plugin'

   export default defineConfig({
     plugins: [
       vue(),
       vike({ prerender: true })  // 若只需 SSR,可去掉 prerender 选项
     ]
   })
   ```

---

## 2. 创建并填充 `renderer` 目录

* 在项目根目录下与 `src` 同级创建 `renderer/` 文件夹。
* 参考官方示例([vike-with-pinia](https://github.com/brillout/vike-with-pinia),[boilerplate-vue-ts](https://github.com/vikejs/vike/tree/main/boilerplates/boilerplate-vue-ts/renderer)),将以下关键文件拷贝过来:

  * `config.ts`
  * `onBeforeRender.ts`
  * `onRenderClient.ts`
  * `onRenderHtml.ts`
  * `app.ts`
  * `types.ts`
  * `usePageContext.ts`

### 2.1 客户端渲染逻辑(`onRenderClient.ts`)

在这里编写浏览器端逻辑(如检测不同浏览器环境等)。

### 2.2 服务端 HTML 模板(`onRenderHtml.ts`)

根据 `pageContext.urlPathname` 判断不同路由,动态生成 `<title>`、`<meta>` 信息,确保中文不乱码请添加:

```html
<meta charset="UTF-8" />
```

示例:

```ts
const documentHtml = escapeInject`<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>${title}</title>
  </head>
  <body>
    <div id="app">${stream}</div>
  </body>
</html>`
```

### 2.3 应用入口(`app.ts`)

在 SSG/SSR 模式下,`main.ts` 和原有 `index.html` 不再生效,需在 `app.ts`:

* 创建 SSR 应用:`createSSRApp`
* 引入 Pinia 并使用 `pinia-plugin-persistedstate`
* 处理 Element Plus 的水合(hydration)错误

---

## 3. 重命名视图目录与页面组件

1. 将 `src/views` 重命名为 `src/pages`,Vike 会自动根据此目录生成路由。
2. 每个页面文件夹内改为 `+Page.vue`:

   ```
   src/pages/
   ├─ about/
   │  └─ +Page.vue    // 对应 /about
   ├─ blog/
   │  └─ +Page.vue    // 对应 /blog
   └─ _error/
      └─ +Page.vue    // 404 或通配
   ```
3. 原先使用 `vue-router` 的跳转改为:

   ```ts
   window.location.href = '/about'
   ```

---

## 4. 客户端专属组件(Client‑only)

对于依赖 `window`、`localStorage` 等浏览器 API 的组件,需要仅在客户端渲染:

```vue
<template>
  <ClientOnly :load="() => import('@/components/MyBrowserOnly.vue')" />
</template>
```

`ClientOnly` 组件可参考 Vike 官方仓库示例。

---

## 5. 处理外部依赖排除问题

如果打包时报 Element Plus 等包被当外部依赖排除,可在 `vite.config.ts` 中新增:

```ts
export default defineConfig({
  // …plugins 配置
  ssr: {
    noExternal: ['element-plus']
  }
})
```

---

## 6. 构建与发布

1. 运行预渲染打包:

   ```bash
   npm run build
   ```
2. 在 `dist/client/` 目录下会生成所有静态 HTML 与资源,直接部署到静态服务器即可,无需额外服务器逻辑。

---

## 7. 建议参考官方示例进行修改
官方示例
[vikejs ](https://github.com/vikejs/vike)
![file](/uploads/oneblog/article/20250713071811859.png)
---

## 小结

* 使用 Vike 可以无缝为已有 Vue3 + Vite + TS 项目添加 SSG 功能,极大提升 SEO 效果与首屏性能。
* 通过动态路由判断,可为每个页面自定义 `<title>`、`<meta>` 信息。
* 注意重命名 `pages` 目录、客户端组件和外部依赖配置,确保打包顺利。

---

## 参考 
https://juejin.cn/post/7341593721099436072
https://blog.csdn.net/qq_34988304/article/details/135835945
https://juejin.cn/post/7483329722497581082
https://vike.dev/
作者的其他文章
微信小程序自定义数据实现级联省市区组件功能
这篇文章完整演示了如何在微信小程序中使用自定义 JSON 数据实现省市区三级联动组件,包含数据准备、组件封装与联动处理,让你轻松掌握实战技巧。
微信小程序自定义数据实现级联省市区组件功能
2025 年最新国内 npm / pnpm / Yarn 镜像源设置指南
2025 年最新国内 npm、pnpm、Yarn 镜像源设置教程,包含多种可用镜像源及 `nrm` 一键切换使用方法,助你快速安装依赖、提升效率。
2025 年最新国内 npm / pnpm / Yarn 镜像源设置指南
前端网站加速:Vue 与纯 HTML 项目配置 CDN 实践指南
本文深入讲解如何在 Vue 和纯 HTML 项目中配置 CDN,提供实战代码示例,并推荐 Cloudflare、AWS CloudFront、腾讯云 CDN、阿里云 CDN、jsDelivr、Fastly 等主流服务商,助力前端性能优化与快速部署。
快速构建高性能前端 —— 推荐 CDNJS 免费公共 CDN 加速服务
CDNJS 是一款免费、开源的公共 CDN 服务,提供全球 Anycast 加速、4,000+ 前端库资源,助力网站快速构建和性能优化。
快速构建高性能前端 —— 推荐 CDNJS 免费公共 CDN 加速服务