peakchao
搜索
peakchao

peakchao

前端开发工程师 | Go 爱好者

联系方式

VitePress 完全指南:从入门到精通

peakchao 2025-12-25 05:51 3 次浏览 0 条评论

VitePress 简介

什么是 VitePress?

VitePress 是 VuePress 的继任者,由 Vue.js 团队开发,基于 Vite 构建。它专为创建文档网站而设计,同时也适用于博客、产品介绍页面等内容驱动型网站。

VitePress 的主要特点:

  • 极速开发体验:基于 Vite 的即时热更新(HMR)
  • Vue 3 驱动:在 Markdown 中使用 Vue 组件
  • 轻量级:生成的静态资源体积小
  • 开箱即用:内置主题、搜索、导航等功能
  • 高度可定制:支持自定义主题和布局

VitePress vs VuePress

特性VitePressVuePress
构建工具ViteWebpack
Vue 版本Vue 3Vue 2/3
开发启动速度毫秒级秒级
热更新速度即时较慢
默认主题现代化设计经典设计
体积更轻量较重

谁在使用 VitePress?

许多知名项目都选择 VitePress 作为文档工具:

  • Vue.js - Vue 3 官方文档
  • Vite - Vite 官方文档
  • Vitest - Vitest 测试框架文档
  • Pinia - Vue 状态管理库文档
  • Element Plus - Vue 3 UI 组件库文档

快速开始

环境要求

  • Node.js 18 或更高版本
  • npm/yarn/pnpm 包管理器

创建新项目

方法一:使用向导创建(推荐)

# 使用 npm
npx vitepress init

# 使用 pnpm
pnpm dlx vitepress init

# 使用 yarn
yarn dlx vitepress init

向导会询问几个简单的问题:

┌  Welcome to VitePress!
│
◇  Where should VitePress initialize the config?
│  ./docs
│
◇  Site title:
│  My Awesome Docs
│
◇  Site description:
│  A VitePress Site
│
◇  Theme:
│  Default Theme + Customization
│
◇  Use TypeScript for config and theme files?
│  Yes
│
◇  Add VitePress npm scripts to package.json?
│  Yes
│
└  Done! Now run npm run docs:dev and start writing.

方法二:手动创建

# 创建项目目录
mkdir my-docs && cd my-docs

# 初始化 package.json
npm init -y

# 安装 VitePress
npm install -D vitepress

# 创建文档目录和首页
mkdir docs && echo '# Hello VitePress' > docs/index.md

package.json 中添加脚本:

{
  "scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:preview": "vitepress preview docs"
  }
}

启动开发服务器

npm run docs:dev

访问 http://localhost:5173 即可预览你的文档站点。


项目结构

标准目录结构

my-docs/
├── docs/
│   ├── .vitepress/
│   │   ├── config.mts          # 配置文件
│   │   ├── theme/
│   │   │   ├── index.ts        # 主题入口
│   │   │   ├── style.css       # 自定义样式
│   │   │   └── components/     # 自定义组件
│   │   └── cache/              # 缓存目录(自动生成)
│   ├── public/                 # 静态资源
│   │   ├── logo.svg
│   │   └── favicon.ico
│   ├── guide/
│   │   ├── index.md            # /guide/
│   │   ├── getting-started.md  # /guide/getting-started
│   │   └── advanced.md         # /guide/advanced
│   ├── api/
│   │   └── index.md            # /api/
│   └── index.md                # 首页
├── package.json
└── tsconfig.json

路由规则

VitePress 使用基于文件的路由:

文件路径对应 URL
docs/index.md/
docs/guide/index.md/guide/
docs/guide/getting-started.md/guide/getting-started
docs/api/reference.md/api/reference

特殊目录说明

  • .vitepress/ - VitePress 配置和主题文件
  • .vitepress/cache/ - 开发缓存,可添加到 .gitignore
  • .vitepress/dist/ - 构建输出目录
  • public/ - 静态资源,会原样复制到输出目录

配置详解

基础配置

创建 .vitepress/config.mts 文件:

import { defineConfig } from 'vitepress'

export default defineConfig({
  // 站点基础配置
  title: 'My Awesome Docs',
  description: 'A VitePress Site',
  lang: 'zh-CN',
  
  // 部署基础路径
  base: '/',
  
  // 构建输出目录
  outDir: './.vitepress/dist',
  
  // 缓存目录
  cacheDir: './.vitepress/cache',
  
  // 源文件目录
  srcDir: './',
  
  // 清理输出目录
  cleanUrls: true,
  
  // 最后更新时间
  lastUpdated: true,
  
  // 头部标签
  head: [
    ['link', { rel: 'icon', href: '/favicon.ico' }],
    ['meta', { name: 'theme-color', content: '#3c8772' }],
    ['meta', { name: 'og:type', content: 'website' }],
    ['meta', { name: 'og:locale', content: 'zh_CN' }],
  ],
})

主题配置

import { defineConfig } from 'vitepress'

export default defineConfig({
  themeConfig: {
    // 站点 Logo
    logo: '/logo.svg',
    
    // 站点标题(显示在导航栏)
    siteTitle: 'My Docs',
    
    // 导航栏
    nav: [
      { text: '指南', link: '/guide/' },
      { text: 'API', link: '/api/' },
      {
        text: '更多',
        items: [
          { text: '更新日志', link: '/changelog' },
          { text: '贡献指南', link: '/contributing' },
        ]
      },
      {
        text: '版本',
        items: [
          { text: 'v1.x', link: '/v1/' },
          { text: 'v2.x (当前)', link: '/' },
        ]
      }
    ],
    
    // 侧边栏
    sidebar: {
      '/guide/': [
        {
          text: '入门',
          collapsed: false,
          items: [
            { text: '简介', link: '/guide/' },
            { text: '快速开始', link: '/guide/getting-started' },
            { text: '配置', link: '/guide/configuration' },
          ]
        },
        {
          text: '进阶',
          collapsed: false,
          items: [
            { text: '主题定制', link: '/guide/theme' },
            { text: '部署', link: '/guide/deploy' },
          ]
        }
      ],
      '/api/': [
        {
          text: 'API 参考',
          items: [
            { text: '配置', link: '/api/config' },
            { text: '运行时 API', link: '/api/runtime' },
          ]
        }
      ]
    },
    
    // 社交链接
    socialLinks: [
      { icon: 'github', link: 'https://github.com/username/repo' },
      { icon: 'twitter', link: 'https://twitter.com/username' },
      { icon: 'discord', link: 'https://discord.gg/invite' },
    ],
    
    // 页脚
    footer: {
      message: 'Released under the MIT License.',
      copyright: 'Copyright © 2024-present My Team'
    },
    
    // 编辑链接
    editLink: {
      pattern: 'https://github.com/username/repo/edit/main/docs/:path',
      text: '在 GitHub 上编辑此页'
    },
    
    // 最后更新时间
    lastUpdated: {
      text: '最后更新于',
      formatOptions: {
        dateStyle: 'short',
        timeStyle: 'short'
      }
    },
    
    // 文档页脚导航
    docFooter: {
      prev: '上一页',
      next: '下一页'
    },
    
    // 大纲配置
    outline: {
      level: [2, 3],
      label: '本页目录'
    },
    
    // 返回顶部文案
    returnToTopLabel: '返回顶部',
    
    // 移动端菜单文案
    sidebarMenuLabel: '菜单',
    
    // 深色模式切换
    darkModeSwitchLabel: '主题',
    lightModeSwitchTitle: '切换到浅色模式',
    darkModeSwitchTitle: '切换到深色模式',
  }
})

Frontmatter 配置

每个 Markdown 文件可以使用 YAML frontmatter 进行页面级配置:

---
title: 页面标题
description: 页面描述
layout: doc
aside: true
outline: [2, 3]
lastUpdated: true

# 首页专用
layout: home
hero:
  name: My Project
  text: 快速构建现代文档
  tagline: 基于 Vite & Vue 的静态站点生成器
  image:
    src: /logo.svg
    alt: Logo
  actions:
    - theme: brand
      text: 快速开始
      link: /guide/getting-started
    - theme: alt
      text: GitHub
      link: https://github.com/username/repo

features:
  - icon: ⚡️
    title: 极速体验
    details: 基于 Vite 的即时服务器启动和闪电般的热更新
  - icon: 🖖
    title: Vue 驱动
    details: 在 Markdown 中使用 Vue 组件,享受 Vue 的强大功能
  - icon: 🛠️
    title: 简单易用
    details: 以最少的配置快速构建美观的文档站点
---

自定义首页

---
layout: home

hero:
  name: VitePress
  text: Vite & Vue 驱动的静态站点生成器
  tagline: 简单、强大、快速
  image:
    src: /logo-large.svg
    alt: VitePress
  actions:
    - theme: brand
      text: 快速开始
      link: /guide/getting-started
    - theme: alt
      text: 在 GitHub 上查看
      link: https://github.com/vuejs/vitepress

features:
  - icon: 📝
    title: 专注于内容
    details: 只需使用 Markdown 即可轻松创建美观的文档站点
  - icon: <svg xmlns="http://www.w3.org/2000/svg" width="32" viewBox="0 0 256 220.8"><path fill="#41B883" d="..."/></svg>
    title: 享受 Vite 体验
    details: 即时服务器启动、闪电般的热更新,以及基于 Rollup 的优化构建
  - icon:
      src: /custom-icon.svg
    title: 高度可定制
    details: 通过 Vite 插件和 Vue 组件扩展你的站点
---

Markdown 扩展

VitePress 在标准 Markdown 基础上提供了丰富的扩展功能。

内部链接

<!-- 相对路径 -->
[快速开始]./getting-started.md
[API 参考]../api/index.md

<!-- 绝对路径 -->
[首页]/index.md
[指南]/guide/

<!-- 锚点链接 -->
[配置详解]#配置详解
[其他页面的锚点]./other-page.md#section

代码块增强

语法高亮

VitePress 使用 Shiki 进行代码高亮,支持几乎所有编程语言。

interface User {
  id: number
  name: string
  email: string
}

function greet(user: User): string {
  return `Hello, ${user.name}!`
}

行高亮

import { defineConfig } from 'vitepress'

export default defineConfig({
  title: 'My Docs',
  description: 'A VitePress Site',
  lang: 'zh-CN',
})

语法:在语言标识符后添加 {行号}{起始行-结束行}

```typescript{1,4-6}
// 高亮第 1 行和第 4-6 行

行号显示

在配置中启用:

export default defineConfig({
  markdown: {
    lineNumbers: true
  }
})

或在单个代码块中启用:

```typescript:line-numbers
// 显示行号

代码聚焦

使用 // [!code focus] 注释聚焦特定行:

export default defineConfig({
  title: 'My Docs', // [!code focus]
  description: 'A VitePress Site',
})

差异对比

使用 // [!code ++]// [!code --] 显示代码差异:

export default {
  data() {
    return {
      msg: 'Removed' // [!code --]
      msg: 'Added' // [!code ++]
    }
  }
}

错误和警告高亮

export default {
  data() {
    return {
      msg: 'Error highlighted' // [!code error]
      msg: 'Warning highlighted' // [!code warning]
    }
  }
}

代码组

使用 :::code-group 创建多标签代码块:

:: code-group

npm install vitepress
pnpm add vitepress
yarn add vitepress

:::

语法:

::: code-group

```bash [npm]
npm install vitepress
pnpm add vitepress

:::


### 自定义容器

VitePress 支持多种提示容器:

::: info 信息
这是一条信息提示
:::

::: tip 提示
这是一条友好的提示
:::

::: warning 警告
这是一条警告信息
:::

::: danger 危险
这是一条危险警告
:::

::: details 点击查看详情
这是折叠的详细内容
:::

语法:

```markdown
::: info 信息
这是一条信息提示
:::

::: tip 提示
这是一条友好的提示
:::

::: warning 警告
这是一条警告信息
:::

::: danger 危险
这是一条危险警告
:::

::: details 点击查看详情
这是折叠的详细内容
:::

GitHub 风格的告警

VitePress 也支持 GitHub 风格的告警语法:

> [!NOTE]
> 强调用户应该注意的信息

> [!TIP]
> 帮助用户更好地完成任务的建议

> [!IMPORTANT]
> 用户成功完成任务所需的关键信息

> [!WARNING]
> 可能导致问题的紧急信息

> [!CAUTION]
> 某些操作可能带来的负面后果

表格

功能支持情况备注
左对齐使用 :---
居中对齐使用 :---:
右对齐使用 ---:

Emoji

VitePress 支持 Emoji 表情:

:tada: :100: :rocket:

效果::tada: :100: :rocket:

目录生成

在任意位置插入 [[toc]] 会生成当前页面的目录:

[[toc]]

数学公式

VitePress 支持 LaTeX 数学公式(需要配置):

// config.mts
export default defineConfig({
  markdown: {
    math: true
  }
})

行内公式:E = mc^2

块级公式:

\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x)

图片懒加载

export default defineConfig({
  markdown: {
    image: {
      lazyLoading: true
    }
  }
})

主题定制

自定义 CSS

创建 .vitepress/theme/style.css

/* 自定义 CSS 变量 */
:root {
  /* 品牌色 */
  --vp-c-brand-1: #5b8dfe;
  --vp-c-brand-2: #3c70dc;
  --vp-c-brand-3: #2655b8;
  --vp-c-brand-soft: rgba(91, 141, 254, 0.14);
  
  /* 首页 Hero 渐变 */
  --vp-home-hero-name-color: transparent;
  --vp-home-hero-name-background: linear-gradient(
    120deg,
    #5b8dfe 30%,
    #41d1ff
  );
  
  /* 首页 Hero 图片渐变 */
  --vp-home-hero-image-background-image: linear-gradient(
    -45deg,
    #5b8dfe 50%,
    #41d1ff 50%
  );
  --vp-home-hero-image-filter: blur(44px);
}

/* 深色模式 */
.dark {
  --vp-c-brand-1: #7aa2ff;
  --vp-c-brand-2: #5b8dfe;
  --vp-c-brand-3: #3c70dc;
}

/* 自定义字体 */
:root {
  --vp-font-family-base: 'Inter', 'Chinese Quotes', 'Inter', ui-sans-serif,
    system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Helvetica, Arial, 'Noto Sans', sans-serif,
    'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  --vp-font-family-mono: 'JetBrains Mono', 'Fira Code', ui-monospace,
    SFMono-Regular, 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono',
    'Courier New', monospace;
}

/* 自定义代码块样式 */
.vp-doc div[class*='language-'] {
  border-radius: 8px;
}

/* 隐藏代码块语言标识 */
.vp-doc div[class*='language-'] > span.lang {
  display: none;
}

/* 自定义链接样式 */
.vp-doc a {
  text-decoration: none;
  border-bottom: 1px solid var(--vp-c-brand-1);
  transition: border-color 0.25s;
}

.vp-doc a:hover {
  border-bottom-color: transparent;
}

主题入口文件

创建 .vitepress/theme/index.ts

import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'

// 导入自定义样式
import './style.css'

// 导入自定义组件
import MyComponent from './components/MyComponent.vue'

export default {
  extends: DefaultTheme,
  
  // 布局增强
  Layout: () => {
    return h(DefaultTheme.Layout, null, {
      // 在导航栏标题之前插入内容
      'nav-bar-title-before': () => h('span', 'Before'),
      
      // 在导航栏标题之后插入内容
      'nav-bar-title-after': () => h('span', 'After'),
      
      // 在导航栏菜单之前插入内容
      'nav-bar-content-before': () => h(MyComponent),
      
      // 在导航栏菜单之后插入内容
      'nav-bar-content-after': () => h('div', 'After Nav'),
      
      // 在侧边栏顶部插入内容
      'sidebar-nav-before': () => h('div', 'Sidebar Top'),
      
      // 在侧边栏底部插入内容
      'sidebar-nav-after': () => h('div', 'Sidebar Bottom'),
      
      // 在文档内容之前插入内容
      'doc-before': () => h('div', 'Before Doc'),
      
      // 在文档内容之后插入内容
      'doc-after': () => h('div', 'After Doc'),
      
      // 在页面底部(页脚之前)插入内容
      'doc-footer-before': () => h('div', 'Before Footer'),
      
      // 在页面最底部插入内容
      'layout-bottom': () => h('div', 'Layout Bottom'),
    })
  },
  
  // 全局增强
  enhanceApp({ app, router, siteData }) {
    // 注册全局组件
    app.component('MyComponent', MyComponent)
    
    // 注册 Vue 插件
    // app.use(SomePlugin)
    
    // 路由守卫
    router.onBeforeRouteChange = (to) => {
      console.log('路由即将改变到:', to)
    }
    
    router.onAfterRouteChanged = (to) => {
      console.log('路由已改变到:', to)
    }
  },
  
  // 设置函数(可选)
  setup() {
    // 这里可以访问 Vue Composition API
  }
} satisfies Theme

可用的布局插槽

VitePress 默认主题提供了以下布局插槽:

插槽名称位置说明
layout-top布局最顶部
layout-bottom布局最底部
nav-bar-title-before导航栏标题之前
nav-bar-title-after导航栏标题之后
nav-bar-content-before导航栏菜单之前
nav-bar-content-after导航栏菜单之后
nav-screen-content-before移动端菜单内容之前
nav-screen-content-after移动端菜单内容之后
sidebar-nav-before侧边栏顶部
sidebar-nav-after侧边栏底部
aside-top右侧边栏顶部
aside-bottom右侧边栏底部
aside-outline-before大纲之前
aside-outline-after大纲之后
aside-ads-before广告位之前
aside-ads-after广告位之后
doc-top文档页面顶部
doc-bottom文档页面底部
doc-before文档内容之前
doc-after文档内容之后
doc-footer-before文档页脚之前
not-found404 页面内容
home-hero-before首页 Hero 之前
home-hero-after首页 Hero 之后
home-hero-info首页 Hero 信息区域
home-hero-image首页 Hero 图片区域
home-features-before首页特性之前
home-features-after首页特性之后

自定义组件

在 Markdown 中使用 Vue 组件

VitePress 允许在 Markdown 文件中直接使用 Vue 组件。

全局组件

在主题入口文件中注册:

// .vitepress/theme/index.ts
import MyButton from './components/MyButton.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.component('MyButton', MyButton)
  }
}

在 Markdown 中使用:

<MyButton text="点击我" />

局部组件

在 Markdown 文件中直接导入:

<script setup>
import CustomDemo from '../components/CustomDemo.vue'
</script>

# 我的页面

下面是一个自定义组件:

<CustomDemo />

常用组件示例

徽章组件

创建 .vitepress/theme/components/Badge.vue

<script setup lang="ts">
defineProps<{
  text: string
  type?: 'info' | 'tip' | 'warning' | 'danger'
}>()
</script>

<template>
  <span class="badge" :class="type">
    {{ text }}
  </span>
</template>

<style scoped>
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.5;
}

.info {
  background-color: var(--vp-c-info-soft);
  color: var(--vp-c-info-1);
}

.tip {
  background-color: var(--vp-c-tip-soft);
  color: var(--vp-c-tip-1);
}

.warning {
  background-color: var(--vp-c-warning-soft);
  color: var(--vp-c-warning-1);
}

.danger {
  background-color: var(--vp-c-danger-soft);
  color: var(--vp-c-danger-1);
}
</style>

代码演示组件

创建 .vitepress/theme/components/CodeDemo.vue

<script setup lang="ts">
import { ref } from 'vue'

defineProps<{
  title?: string
}>()

const showCode = ref(false)
</script>

<template>
  <div class="code-demo">
    <div class="demo-header">
      <span class="title">{{ title || '示例' }}</span>
      <button @click="showCode = !showCode">
        {{ showCode ? '隐藏代码' : '查看代码' }}
      </button>
    </div>
    
    <div class="demo-preview">
      <slot name="preview" />
    </div>
    
    <div v-show="showCode" class="demo-code">
      <slot name="code" />
    </div>
  </div>
</template>

<style scoped>
.code-demo {
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  margin: 16px 0;
  overflow: hidden;
}

.demo-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background-color: var(--vp-c-bg-soft);
  border-bottom: 1px solid var(--vp-c-divider);
}

.title {
  font-weight: 600;
  font-size: 14px;
}

.demo-header button {
  padding: 4px 12px;
  border: 1px solid var(--vp-c-brand-1);
  border-radius: 4px;
  background: transparent;
  color: var(--vp-c-brand-1);
  cursor: pointer;
  font-size: 12px;
}

.demo-header button:hover {
  background-color: var(--vp-c-brand-soft);
}

.demo-preview {
  padding: 24px;
}

.demo-code {
  border-top: 1px solid var(--vp-c-divider);
}

.demo-code :deep(div[class*='language-']) {
  margin: 0;
  border-radius: 0;
}
</style>

使用 VitePress 内置组件

VitePress 提供了一些内置组件:

VPTeamMembers

展示团队成员:

<script setup>
import { VPTeamMembers } from 'vitepress/theme'

const members = [
  {
    avatar: 'https://github.com/yyx990803.png',
    name: 'Evan You',
    title: 'Creator',
    links: [
      { icon: 'github', link: 'https://github.com/yyx990803' },
      { icon: 'twitter', link: 'https://twitter.com/youyuxi' }
    ]
  },
  // 更多成员...
]
</script>

# 我们的团队

<VPTeamMembers size="small" :members="members" />

ClientOnly

包裹只在客户端渲染的组件:

<ClientOnly>
  <NonSSRFriendlyComponent />
</ClientOnly>

国际化 (i18n)

配置多语言

import { defineConfig } from 'vitepress'

export default defineConfig({
  locales: {
    root: {
      label: '简体中文',
      lang: 'zh-CN',
      link: '/',
      themeConfig: {
        nav: [
          { text: '指南', link: '/guide/' },
        ],
        sidebar: {
          '/guide/': [
            { text: '快速开始', link: '/guide/getting-started' }
          ]
        },
        docFooter: {
          prev: '上一页',
          next: '下一页'
        },
        outline: {
          label: '本页目录'
        },
        lastUpdated: {
          text: '最后更新于'
        },
        editLink: {
          pattern: 'https://github.com/user/repo/edit/main/docs/:path',
          text: '在 GitHub 上编辑此页'
        }
      }
    },
    en: {
      label: 'English',
      lang: 'en',
      link: '/en/',
      themeConfig: {
        nav: [
          { text: 'Guide', link: '/en/guide/' },
        ],
        sidebar: {
          '/en/guide/': [
            { text: 'Getting Started', link: '/en/guide/getting-started' }
          ]
        },
        docFooter: {
          prev: 'Previous',
          next: 'Next'
        },
        outline: {
          label: 'On this page'
        },
        lastUpdated: {
          text: 'Last updated'
        },
        editLink: {
          pattern: 'https://github.com/user/repo/edit/main/docs/:path',
          text: 'Edit this page on GitHub'
        }
      }
    }
  }
})

目录结构

docs/
├── index.md          # 中文首页 (/)
├── guide/
│   ├── index.md      # 中文指南 (/guide/)
│   └── getting-started.md
├── en/
│   ├── index.md      # 英文首页 (/en/)
│   └── guide/
│       ├── index.md  # 英文指南 (/en/guide/)
│       └── getting-started.md
└── .vitepress/
    └── config.mts

语言切换组件

VitePress 会自动在导航栏显示语言切换器。你也可以使用 useData 组合式函数获取当前语言:

<script setup>
import { useData } from 'vitepress'

const { lang, site, page, frontmatter, localeIndex } = useData()
</script>

<template>
  <p>当前语言: {{ lang }}</p>
  <p>语言索引: {{ localeIndex }}</p>
</template>

搜索功能

本地搜索

VitePress 内置了本地全文搜索功能:

export default defineConfig({
  themeConfig: {
    search: {
      provider: 'local',
      options: {
        locales: {
          zh: {
            translations: {
              button: {
                buttonText: '搜索文档',
                buttonAriaLabel: '搜索文档'
              },
              modal: {
                noResultsText: '无法找到相关结果',
                resetButtonTitle: '清除查询条件',
                footer: {
                  selectText: '选择',
                  navigateText: '切换',
                  closeText: '关闭'
                }
              }
            }
          }
        },
        // 排除某些页面
        _render(src, env, md) {
          const html = md.render(src, env)
          if (env.frontmatter?.search === false) {
            return ''
          }
          return html
        }
      }
    }
  }
})

Algolia DocSearch

对于大型文档站点,推荐使用 Algolia DocSearch:

export default defineConfig({
  themeConfig: {
    search: {
      provider: 'algolia',
      options: {
        appId: 'YOUR_APP_ID',
        apiKey: 'YOUR_SEARCH_API_KEY',
        indexName: 'YOUR_INDEX_NAME',
        locales: {
          zh: {
            placeholder: '搜索文档',
            translations: {
              button: {
                buttonText: '搜索',
                buttonAriaLabel: '搜索'
              },
              modal: {
                searchBox: {
                  resetButtonTitle: '清除查询条件',
                  resetButtonAriaLabel: '清除查询条件',
                  cancelButtonText: '取消',
                  cancelButtonAriaLabel: '取消'
                },
                startScreen: {
                  recentSearchesTitle: '搜索历史',
                  noRecentSearchesText: '没有搜索历史',
                  saveRecentSearchButtonTitle: '保存至搜索历史',
                  removeRecentSearchButtonTitle: '从搜索历史中移除',
                  favoriteSearchesTitle: '收藏',
                  removeFavoriteSearchButtonTitle: '从收藏中移除'
                },
                errorScreen: {
                  titleText: '无法获取结果',
                  helpText: '你可能需要检查你的网络连接'
                },
                footer: {
                  selectText: '选择',
                  navigateText: '切换',
                  closeText: '关闭',
                  searchByText: '搜索提供者'
                },
                noResultsScreen: {
                  noResultsText: '无法找到相关结果',
                  suggestedQueryText: '你可以尝试查询',
                  reportMissingResultsText: '你认为该查询应该有结果?',
                  reportMissingResultsLinkText: '点击反馈'
                }
              }
            }
          }
        }
      }
    }
  }
})

部署指南

构建项目

npm run docs:build

构建输出默认位于 .vitepress/dist 目录。

预览构建产物

npm run docs:preview

部署到不同平台

GitHub Pages

  1. config.mts 中设置正确的 base
export default defineConfig({
  base: '/your-repo-name/'
})
  1. 创建 .github/workflows/deploy.yml
name: Deploy VitePress site to GitHub Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          
      - name: Setup Pages
        uses: actions/configure-pages@v4
        
      - name: Install dependencies
        run: npm ci
        
      - name: Build with VitePress
        run: npm run docs:build
        
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: docs/.vitepress/dist

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Netlify

  1. 创建 netlify.toml
[build]
  command = "npm run docs:build"
  publish = "docs/.vitepress/dist"

[build.environment]
  NODE_VERSION = "20"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Vercel

  1. 创建 vercel.json
{
  "buildCommand": "npm run docs:build",
  "outputDirectory": "docs/.vitepress/dist",
  "framework": "vitepress"
}

Cloudflare Pages

  1. 在 Cloudflare Pages 控制台设置:
    • 构建命令: npm run docs:build
    • 输出目录: docs/.vitepress/dist
    • Node.js 版本: 20

Docker

创建 Dockerfile

# 构建阶段
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run docs:build

# 生产阶段
FROM nginx:alpine

COPY --from=builder /app/docs/.vitepress/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

创建 nginx.conf

server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # 处理 SPA 路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 启用 gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 缓存静态资源
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

性能优化

1. 启用 MPA 模式

对于大型文档站点,可以考虑启用 MPA(多页面应用)模式:

export default defineConfig({
  mpa: true
})

2. 配置资源预加载

export default defineConfig({
  head: [
    // DNS 预解析
    ['link', { rel: 'dns-prefetch', href: 'https://fonts.gstatic.com' }],
    // 预连接
    ['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
  ]
})

3. 图片优化

export default defineConfig({
  markdown: {
    image: {
      // 启用懒加载
      lazyLoading: true
    }
  }
})

4. 代码分割

VitePress 默认会对页面进行代码分割。对于自定义组件,可以使用动态导入:

<script setup>
import { defineAsyncComponent } from 'vue'

const HeavyComponent = defineAsyncComponent(() =>
  import('./components/HeavyComponent.vue')
)
</script>

5. 限制搜索索引范围

export default defineConfig({
  themeConfig: {
    search: {
      provider: 'local',
      options: {
        miniSearch: {
          // 限制搜索字段
          searchOptions: {
            fuzzy: 0.2,
            prefix: true,
            boost: { title: 4, text: 2, titles: 1 }
          }
        }
      }
    }
  }
})

6. 缓存配置

export default defineConfig({
  // 启用缓存
  cacheDir: './.vitepress/cache',
  
  vite: {
    // 构建缓存
    build: {
      chunkSizeWarningLimit: 500
    }
  }
})

最佳实践

1. 目录组织

docs/
├── index.md                 # 首页
├── guide/                   # 用户指南
│   ├── index.md
│   ├── getting-started.md
│   └── ...
├── api/                     # API 文档
│   ├── index.md
│   └── ...
├── examples/                # 示例
│   └── ...
├── blog/                    # 博客(可选)
│   └── ...
├── public/                  # 静态资源
│   ├── images/
│   ├── logo.svg
│   └── favicon.ico
└── .vitepress/
    ├── config.mts           # 主配置文件
    ├── theme/
    │   ├── index.ts         # 主题入口
    │   ├── style.css        # 自定义样式
    │   └── components/      # 自定义组件
    └── cache/               # 缓存目录

2. 配置文件拆分

对于大型项目,可以拆分配置:

// .vitepress/config.mts
import { defineConfig } from 'vitepress'
import { nav } from './configs/nav'
import { sidebar } from './configs/sidebar'
import { head } from './configs/head'

export default defineConfig({
  title: 'My Docs',
  description: 'A VitePress Site',
  head,
  themeConfig: {
    nav,
    sidebar,
  }
})
// .vitepress/configs/nav.ts
import type { DefaultTheme } from 'vitepress'

export const nav: DefaultTheme.NavItem[] = [
  { text: '指南', link: '/guide/' },
  { text: 'API', link: '/api/' },
]
// .vitepress/configs/sidebar.ts
import type { DefaultTheme } from 'vitepress'

export const sidebar: DefaultTheme.Sidebar = {
  '/guide/': [
    {
      text: '入门',
      items: [
        { text: '简介', link: '/guide/' },
        { text: '快速开始', link: '/guide/getting-started' },
      ]
    }
  ]
}

3. Markdown 写作规范

  • 使用语义化的标题层级(h1 仅用于页面标题)
  • 使用适当的代码块语言标识
  • 为所有图片添加 alt 文本
  • 使用相对链接引用其他文档
  • 利用 Frontmatter 设置页面元数据

4. Git 忽略配置

添加到 .gitignore

# VitePress
docs/.vitepress/cache
docs/.vitepress/dist
node_modules

# 本地环境
.env.local
*.local

5. TypeScript 配置

创建 tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "jsx": "preserve",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "types": ["vitepress/client"],
    "paths": {
      "@/*": ["./docs/.vitepress/*"]
    }
  },
  "include": ["docs/.vitepress/**/*.ts", "docs/.vitepress/**/*.vue"],
  "exclude": ["node_modules"]
}

6. 运行时数据与构建时数据

VitePress 提供了强大的数据加载功能:

构建时数据加载

创建 .vitepress/theme/loaders/data.data.ts

import { createContentLoader } from 'vitepress'

export default createContentLoader('blog/**/*.md', {
  excerpt: true,
  transform(rawData) {
    return rawData
      .sort((a, b) => {
        return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
      })
      .map(page => ({
        title: page.frontmatter.title,
        url: page.url,
        date: page.frontmatter.date,
        excerpt: page.excerpt
      }))
  }
})

在组件中使用:

<script setup>
import { data as posts } from '../loaders/data.data'
</script>

<template>
  <div v-for="post in posts" :key="post.url">
    <a :href="post.url">{{ post.title }}</a>
    <span>{{ post.date }}</span>
  </div>
</template>

运行时数据访问

<script setup>
import { useData, useRoute, useRouter } from 'vitepress'

const { site, page, frontmatter, lang, theme } = useData()
const route = useRoute()
const router = useRouter()

// 获取当前页面信息
console.log(page.value.title)
console.log(frontmatter.value)

// 路由导航
router.go('/guide/')
</script>

高级扩展

Vite 插件集成

import { defineConfig } from 'vitepress'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Icons from 'unplugin-icons/vite'

export default defineConfig({
  vite: {
    plugins: [
      // 自动导入组件
      Components({
        dirs: ['docs/.vitepress/theme/components'],
        include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
      }),
      
      // 自动导入 API
      AutoImport({
        imports: ['vue', '@vueuse/core'],
      }),
      
      // 图标支持
      Icons({
        autoInstall: true,
      }),
    ],
    
    // 优化依赖
    optimizeDeps: {
      include: ['vue', '@vueuse/core'],
      exclude: ['vitepress']
    },
    
    // 服务器配置
    server: {
      port: 5173,
      host: true,
    },
    
    // 构建配置
    build: {
      chunkSizeWarningLimit: 1000,
      rollupOptions: {
        output: {
          manualChunks: {
            'vue-vendor': ['vue', 'vue-router'],
          }
        }
      }
    }
  }
})

PWA 支持

安装依赖:

npm install -D @vite-pwa/vitepress

配置:

import { defineConfig } from 'vitepress'
import { withPwa } from '@vite-pwa/vitepress'

export default withPwa(
  defineConfig({
    // VitePress 配置
    title: 'My Docs',
    
    pwa: {
      mode: 'development',
      registerType: 'autoUpdate',
      includeAssets: ['favicon.ico', 'logo.svg'],
      manifest: {
        name: 'My Documentation',
        short_name: 'MyDocs',
        theme_color: '#ffffff',
        icons: [
          {
            src: 'pwa-192x192.png',
            sizes: '192x192',
            type: 'image/png',
          },
          {
            src: 'pwa-512x512.png',
            sizes: '512x512',
            type: 'image/png',
          },
        ],
      },
      workbox: {
        globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
      },
    },
  })
)

自定义 Markdown 渲染

import { defineConfig } from 'vitepress'
import markdownItFootnote from 'markdown-it-footnote'
import markdownItTaskLists from 'markdown-it-task-lists'

export default defineConfig({
  markdown: {
    // 启用行号
    lineNumbers: true,
    
    // 启用数学公式
    math: true,
    
    // 自定义代码块主题
    theme: {
      light: 'github-light',
      dark: 'github-dark'
    },
    
    // 图片配置
    image: {
      lazyLoading: true
    },
    
    // 锚点配置
    anchor: {
      permalink: true,
      permalinkSymbol: '#',
      permalinkBefore: true
    },
    
    // Markdown-it 配置
    config: (md) => {
      // 使用 markdown-it 插件
      md.use(markdownItFootnote)
      md.use(markdownItTaskLists)
      
      // 自定义渲染规则
      const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
        return self.renderToken(tokens, idx, options)
      }
      
      md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
        const token = tokens[idx]
        const href = token.attrGet('href')
        
        // 外部链接添加 target="_blank"
        if (href && href.startsWith('http')) {
          token.attrSet('target', '_blank')
          token.attrSet('rel', 'noopener noreferrer')
        }
        
        return defaultRender(tokens, idx, options, env, self)
      }
    }
  }
})

故障排除

常见问题

1. 构建失败:内存不足

# 增加 Node.js 内存限制
NODE_OPTIONS=--max-old-space-size=8192 npm run docs:build

2. 开发服务器热更新失效

检查文件监听限制:

# Linux
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# macOS
# 通常不需要调整

3. 图片无法显示

确保图片路径正确:

<!-- 正确:使用绝对路径 -->
![Logo]/images/logo.png

<!-- 正确:使用相对路径 -->
![Logo]./images/logo.png

<!-- 错误:路径不存在 -->
![Logo]images/logo.png

4. 代码高亮不生效

确保使用正确的语言标识符:

```javascript
// 正确
// 正确(缩写)
// 错误(区分大小写)

#### 5. 自定义组件未生效

确保组件已正确注册:

```typescript
// .vitepress/theme/index.ts
import MyComponent from './components/MyComponent.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.component('MyComponent', MyComponent)
  }
}

参考资料


本文持续更新中,如有问题或建议,欢迎反馈。

评论 (0)

请先登录后再发表评论

暂无评论,来发表第一条评论吧!