VitePress 站点配置完全指南:site-config 全量选项解析与源码级原理
2026/9/21 2:01:35 网站建设 项目流程
  • 前端
  • 文档

【免费下载链接】vitepress

Vite & Vue powered static site generator.

项目地址:https://gitcode.com/gh_mirrors/vi/vitepress
点击查看免费下载

本指南以 VitePress 官方文档《サイト設定》为骨架,系统梳理应用级(App-Level)站点配置的全部选项——从配置文件解析、站点元数据、路由与构建选项,到主题外观、Markdown/Vite/Vue 集成与五大构建钩子(Build Hooks)。读完本文,你将能够独立完成.vitepress/config.ts的编写、排查构建问题,并借助源码理解每个配置项背后的真实行为,将其用于多语言、子路径部署、SEO 与 PWA 等实战场景。

概述:配置文件的解析与加载

配置文件解析(Config Resolution)

配置文件固定从<root>/.vitepress/config.[ext]解析,其中<root>为项目根目录(即包含.vitepress的目录),[ext]支持.js.ts.mjs.mts四种扩展名,TypeScript 开箱即用。这一点与源码src/node/config.ts中的supportedConfigExtensions = ['js', 'ts', 'mjs', 'mts']完全一致,且解析顺序会同时尝试config/index.[ext]config.[ext]两种形态。

配置文件推荐使用 ES Modules 语法,并以默认导出(default export)的形式输出配置对象:

export default { // 应用级设置 lang: 'en-US', title: 'VitePress', description: 'Vite & Vue powered static site generator.', ... }

resolveConfig(见 src/node/config.ts)会完成以下解析流程:归一化 root 为绝对路径 → 加载用户配置 → 解析站点数据(resolveSiteData)→ 解析srcDir/assetsDir/outDir/cacheDir等路径 → 决定主题目录(存在.vitepress/theme时使用用户主题,否则回退到默认主题DEFAULT_THEME_PATH)→ 解析页面列表。解析后的SiteConfig会挂载到全局global.VITEPRESS_CONFIG,供 content loader 等模块共享。

动态(异步)配置

当配置需要动态生成时,可以默认导出一个(异步)函数:

import { defineConfig } from 'vitepress' export default async () => { const posts = await (await fetch('https://my-cms.com/blog-posts')).json() return defineConfig({ // 应用级设置 lang: 'en-US', title: 'VitePress', description: 'Vite & Vue powered static site generator.', // 主题级设置 themeConfig: { sidebar: [ ...posts.map((post) => ({ text: post.name, link: `/posts/${post.name}` })) ] } }) }

也可以直接使用顶层await(Top-Level Await):

import { defineConfig } from 'vitepress' const posts = await (await fetch('https://my-cms.com/blog-posts')).json() export default defineConfig({ // 应用级设置 lang: 'en-US', title: 'VitePress', description: 'Vite & Vue powered static site generator.', // 主题级设置 themeConfig: { sidebar: [ ...posts.map((post) => ({ text: post.name, link: `/posts/${post.name}` })) ] } })

从源码看,resolveUserConfig会通过resolveConfigExtends对函数型配置进行求值(typeof config === 'function' ? config() : config),且支持extends字段递归合并基础配置,详见 src/node/config.ts。

配置的智能提示(Config Intellisense)

使用defineConfig辅助函数可以获得 TypeScript 类型补全,在支持的语言服务中,JavaScript 与 TypeScript 文件都能获得提示:

import { defineConfig } from 'vitepress' export default defineConfig({ // ... })

其实现位于 src/node/config.ts:defineConfig<ThemeConfig = DefaultTheme.Config>(config)本质上只是返回传入的配置对象,借助泛型默认值将类型约束到默认主题的配置结构。

带类型的主题配置(Typed Theme Config)

默认情况下,defineConfig假定主题配置的类型为DefaultTheme.Config

import { defineConfig } from 'vitepress' export default defineConfig({ themeConfig: { // 类型为 `DefaultTheme.Config` } })

使用自定义主题并希望对其themeConfig做类型检查时,改用defineConfigWithTheme并通过泛型传入自定义主题的配置类型:

import { defineConfigWithTheme } from 'vitepress' import type { ThemeConfig } from 'your-theme' export default defineConfigWithTheme<ThemeConfig>({ themeConfig: { // 类型为 `ThemeConfig` } })

注意源码中defineConfigWithTheme已被标注为@deprecated use defineConfig instead(src/node/config.ts),但从当前文档与类型层面它依然可用;推荐新代码直接使用defineConfig<ThemeConfig>({ ... })的泛型写法。

Vite・Vue・Markdown 的配置入口

  • Vite:无需单独的 Vite 配置文件,直接在 VitePress 配置的 vite 选项中提供 Vite 配置。类型为import('vite').UserConfig
  • Vue:VitePress 内置了官方 Vue 插件@vitejs/plugin-vue,其选项通过 vue 传入。类型为import('@vitejs/plugin-vue').Options
  • Markdown:默认的 Markdown-It 实例可通过 markdown 选项自定义,选项类型为MarkdownOption(源码定义见 src/node/markdown/markdown.ts)。

站点元数据(Site Metadata)

title

  • 类型:string
  • 默认值:VitePress
  • 页面级覆盖:frontmatter 的 title

站点的标题。默认主题会将其显示在导航栏中。若未定义titleTemplate,它还会作为每个页面标题的默认后缀。各页面最终标题 = 该页首个<h1>标题文本 + 全局title后缀。例如:

export default { title: 'My Awesome Site' }
# Hello

该页面的标题即为Hello | My Awesome Site。源码中默认值由 src/node/config.ts 的userConfig.title || 'VitePress'提供。

titleTemplate

  • 类型:string | boolean
  • 页面级覆盖:frontmatter 的 titleTemplate

用于定制每个页面标题的后缀或整体标题。例如:

export default { title: 'My Awesome Site', titleTemplate: 'Custom Suffix' }
# Hello

页面标题为Hello | Custom Suffix。若要完全自定义标题的渲染方式,可在titleTemplate中使用:title符号:

export default { titleTemplate: ':title - Custom Suffix' }

其中:title会被替换为从页面首个<h1>推断出的文本,上面的例子将渲染为Hello - Custom Suffix。设置为false可禁用标题后缀。

description

  • 类型:string
  • 默认值:A VitePress site
  • 页面级覆盖:frontmatter 的 description

站点的描述,会以<meta>标签输出到页面 HTML 中:

export default { description: 'A VitePress site' }

对应源码默认值见 src/node/config.ts:userConfig.description || 'A VitePress site'

head

  • 类型:HeadConfig[]
  • 默认值:[]
  • 页面级追加:frontmatter 的 head

向页面 HTML 的<head>中额外输出的元素。用户添加的标签会渲染在 VitePress 自带标签之后、</head>之前。其类型定义为:

type HeadConfig = | [string, Record<string, string>] | [string, Record<string, string>, string]

即三元组形式[标签名, 属性对象, 可选的内联内容],实际类型声明见 types/shared.d.ts。需要注意:resolveSiteDataHead(src/node/config.ts)会自动在 head 中注入check-dark-modecheck-mac-os两个内联脚本(MPA 模式下仅注入后者),因此实际输出的<head>会比用户配置的多出这些由框架管理的元素。

示例:添加 favicon
export default { head: [['link', { rel: 'icon', href: '/favicon.ico' }]] } // favicon.ico 需放在 public 目录;若设置了 base,则使用 /base/favicon.ico /* 输出结果: <link rel="icon" href="/favicon.ico"> */
示例:添加 Google Fonts
export default { head: [ [ 'link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' } ], [ 'link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' } ], [ 'link', { href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' } ] ] } /* 输出结果: <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet"> */
示例:注册 Service Worker
export default { head: [ [ 'script', { id: 'register-sw' }, `;(() => { if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') } })()` ] ] } /* 输出结果: <script id="register-sw"> ;(() => { if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') } })() </script> */
示例:接入 Google Analytics
export default { head: [ [ 'script', { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' } ], [ 'script', {}, `window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'TAG_ID');` ] ] } /* 输出结果: <script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'TAG_ID'); </script> */

lang

  • 类型:string
  • 默认值:en-US

站点的语言属性,会输出为页面 HTML 的<html lang="en-US">

export default { lang: 'en-US' }

base

  • 类型:string
  • 默认值:/

站点部署的基础 URL。当部署在子路径下(如 GitHub Pages 的https://foo.github.io/bar/)时,需要将base设为'/bar/',且必须以/开头和结尾。base会自动添加到其他选项中以/开头的 URL 之前,因此只需设置一次:

export default { base: '/base/' }

源码中的normalizeSiteBase(src/node/config.ts)会做归一化处理:自动补末尾斜杠;若 base 以.开头但并非精确的'./'相对形式(isRelativeBase)则直接抛错;不是相对 base 且不是外部 URL、又不以/开头时自动补前导斜杠。因此除了/bar/这类绝对子路径,还可以使用'./'相对 base 让产物可移动到任意子路径下部署。

路由(Routing)

cleanUrls

  • 类型:boolean
  • 默认值:false

设为true后,URL 末尾的.html会被移除,同时参见生成干净 URL一节。

::: warning 需要服务器配置 某些托管环境需要额外配置:访问/foo时能不经过重定向直接返回/foo.html。 :::

源码层面,cleanUrls的默认解析见 src/node/config.ts(cleanUrls: !!userConfig.cleanUrls)。另外当base为相对路径且cleanUrls开启时,构建阶段会输出警告(cleanUrls with a relative base needs server-side rewrites and breaks file:// browsing,见 src/node/config.ts),提示相对 base 与 cleanUrls 组合需要服务端重写支持。

rewrites

  • 类型:Record<string, string>

定义目录与 URL 之间的自定义映射,详见路由:路由重写:

export default { rewrites: { 'source/:page': 'destination/:page' } }

从类型定义看,rewrites还支持函数形式((id: string) => string)(见 src/node/siteConfig.ts),解析后会生成正反向两张映射表map/inv挂在SiteConfig.rewrites上。

构建(Build)

srcDir

  • 类型:string
  • 默认值:.

存放 Markdown 页面源码的目录(相对于项目根目录),参见根目录与源码目录:

export default { srcDir: './src' }

srcExclude

  • 类型:string[]
  • 默认值:undefined

匹配要从源码中排除的 Markdown 文件的 glob 模式(语法参考 fast-glob):

export default { srcExclude: ['**/README.md', '**/TODO.md'] }

outDir

  • 类型:string
  • 默认值:./.vitepress/dist

构建输出目录(相对于项目根目录):

export default { outDir: '../public' }

assetsDir

  • 类型:string
  • 默认值:assets

生成资源(构建产物)存放的子目录名,路径相对于outDir内部解析:

export default { assetsDir: 'static' }

源码 src/node/config.ts 会校验assetsDir解析后必须位于outDir之内,否则抛出assetsDir cannot be set to a location outside of the outDir错误。

cacheDir

  • 类型:string
  • 默认值:./.vitepress/cache

缓存文件目录(相对于项目根目录),参考 Vite 的 cacheDir:

export default { cacheDir: './.vitepress/.vite' }

ignoreDeadLinks

  • 类型:boolean | 'localhostLinks' | (string | RegExp | ((link: string, source: string) => boolean))[]
  • 默认值:false

设为true时,存在死链也不会导致构建失败。设为'localhostLinks'时,仅跳过对localhost链接的检查,其他死链仍会使构建失败:

export default { ignoreDeadLinks: true }

也可以指定为精确 URL 字符串、正则表达式、自定义过滤函数组成的数组:

export default { ignoreDeadLinks: [ // 精确忽略 "/playground" '/playground', // 忽略所有 localhost 链接 /^https?:\/\/localhost/, // 忽略路径中包含 "/repl/" 的链接 /\/repl\//, // 自定义函数: 忽略包含 "ignore" 的链接 (url) => { return url.toLowerCase().includes('ignore') } ] }

类型定义中该过滤函数签名为(link: string, source: string) => boolean(见 src/node/siteConfig.ts),即第二个参数还能拿到链接所在源文件的信息,便于做更精细的判定。

mpa

  • 类型:boolean
  • 默认值:false

设为true时,生产构建将以 MPA 模式进行。MPA 模式默认以 0kb 客户端 JavaScript 交付页面,代价是禁用客户端导航,需要交互的页面必须显式选择接入(opt-in)。其类型定义标注为@experimental,默认解析见 src/node/config.ts(mpa: !!userConfig.mpa)。

主题相关(Theming)

appearance

  • 类型:boolean | 'dark' | 'force-dark' | 'force-auto' | import('@vueuse/core').UseDarkOptions
  • 默认值:true

是否启用深色模式(在<html>上添加.dark类):

  • true:跟随用户的环境偏好。
  • 'dark':默认使用深色,用户仍可切换。
  • false:用户无法切换主题。
  • 'force-dark':始终固定深色(不可切换)。
  • 'force-auto':始终跟随系统偏好(不可切换)。

该选项会插入一个内联脚本,从本地存储vitepress-theme-appearance(常量APPEARANCE_KEY定义于 src/shared/shared.ts)恢复外观设置,从而在页面渲染前应用.dark类以防止闪烁(FOUC)。appearance.initialValue仅支持'dark' | undefined,不能使用 Ref 或 getter。

源码实现值得展开:resolveSiteDataHead(src/node/config.ts)在appearance非空时自动注入id="check-dark-mode"的内联脚本,脚本内容根据 appearance 模式分为三种——force-dark直接加类;force-auto通过matchMedia('(prefers-color-scheme: dark)')判定;普通模式则优先读localStoragevitepress-theme-appearance,再回退到initialValue ?? 'auto'。另外注意 MPA 模式下(userConfig?.mpa为真)该脚本不会被注入。

lastUpdated

  • 类型:boolean
  • 默认值:false

使用 Git 获取每个页面的最后更新时间戳。时间戳会包含在每页数据中,可通过useData引用。使用默认主题时开启该选项会在页面底部显示最后更新时间,文案可通过themeConfig.lastUpdated.text定制。

源码中lastUpdated的解析为userConfig.lastUpdated ?? !!userConfig.themeConfig?.lastUpdated(src/node/config.ts),即只要任一处开启即生效,其底层时间戳获取逻辑位于 src/node/utils/getGitTimestamp.ts。

自定义(Customization)

markdown

  • 类型:MarkdownOption

Markdown 解析器的配置。VitePress 使用 Markdown-it 作为解析器、Shiki 做语法高亮,可按需指定各类 Markdown 相关选项:

export default { markdown: {...} }

可用的选项可查看类型定义与 JSDoc。这里结合源码给出高频选项速查:

  • preConfig/config:在应用内置插件之前/之后配置 markdown-it 实例的回调;
  • theme:语法高亮主题,支持{ light: 'github-light', dark: 'github-dark' }双主题对象,默认即为此双主题(src/node/markdown/markdown.ts);
  • lineNumbers:代码块行号(依赖preWrapper,默认false);
  • snippet/include<<<代码片段导入与<!-- @include: path -->Markdown 包含;
  • emojitasklistfootnoteattrsanchortocmathcontainergfmAlertsimagecomponentfrontmattersfc等开关;
  • externalLinks:外部链接属性,默认{ target: '_blank', rel: 'noreferrer' }(src/node/markdown/markdown.ts)。

vite

  • 类型:import('vite').UserConfig

向内部的 Vite 开发服务器/打包器传入原始的 Vite Config:

export default { vite: { // Vite 配置 } }

vue

  • 类型:import('@vitejs/plugin-vue').Options

将选项原样传给内部的@vitejs/plugin-vue实例:

export default { vue: { // @vitejs/plugin-vue 选项 } }

构建钩子(Build Hooks)

VitePress 的构建钩子可用于为站点添加功能或行为,官方文档列出的典型用途包括:

  • 站点地图(Sitemap)
  • 搜索索引(Search index)
  • PWA
  • Teleport(SSG 期间传送内容的处理)

buildEnd

  • 类型:(siteConfig: SiteConfig) => Awaitable<void>

buildEnd是构建 CLI 钩子:在构建(SSG)完成之后、VitePress CLI 进程退出之前执行:

export default { async buildEnd(siteConfig) { // ... } }

适合在此生成 RSS feed 等一次性收尾任务(类型注释见 src/node/siteConfig.ts)。

postRender

  • 类型:(context: SSGContext) => Awaitable<SSGContext | void>

postRender是 SSG 渲染完成时调用的构建钩子,可用于处理 SSG 期间的 teleport 内容:

export default { async postRender(context) { // ... } }
interface SSGContext { content: string teleports?: Record<string, string> [key: string]: any }

类型声明见 types/shared.d.ts,其中还包含框架内部使用的vpIcons: Set<string>(SSR 期间通过useIcon注册的图标集合)。

transformHead

  • 类型:(context: TransformContext) => Awaitable<HeadConfig[]>

transformHead是在生成每个页面之前转换 head 的构建钩子,可添加无法在配置文件中静态声明的 head 元素。只需返回新增的部分,框架会自动与既有 head 合并。

::: warning 不要修改context内的值。 :::

export default { async transformHead(context) { // ... } }
interface TransformContext { page: string // 例如: index.md(相对于 srcDir) assets: string[] // 已解析的公开 URL(非 js/css 资源) siteConfig: SiteConfig siteData: SiteData pageData: PageData title: string description: string head: HeadConfig[] content: string }

该钩子只在静态站点生成(build)阶段调用,开发模式下不会执行。若需在开发模式下动态添加 head 元素,改用transformPageData

export default { transformPageData(pageData) { pageData.frontmatter.head ??= [] pageData.frontmatter.head.push([ 'meta', { name: 'og:title', content: pageData.frontmatter.layout === 'home' ? `VitePress` : `${pageData.title} | VitePress` } ]) } }
示例:添加规范 URL 的<link>
export default { transformPageData(pageData) { const canonicalUrl = `https://example.com/${pageData.relativePath}` .replace(/index\.md$/, '') .replace(/\.md$/, '.html') pageData.frontmatter.head ??= [] pageData.frontmatter.head.push([ 'link', { rel: 'canonical', href: canonicalUrl } ]) } }

transformHtml

  • 类型:(code: string, id: string, context: TransformContext) => Awaitable<string | void>

transformHtml是在每个页面的内容写入磁盘之前进行转换的构建钩子。

::: warning 不要修改context内的值。此外,修改 HTML 可能引发运行时水合(hydration)问题。 :::

export default { async transformHtml(code, id, context) { // ... } }

transformPageData

  • 类型:(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>

transformPageData是转换每个页面pageData的钩子,既可以就地修改pageData,也可以返回变更值让其合并:

::: warning 不要修改context内的值。若在其中执行网络请求或重计算(如图像生成),会影响开发服务器的性能,可考虑用process.env.NODE_ENV === 'production'做条件分支。 :::

export default { async transformPageData(pageData, { siteConfig }) { pageData.contributors = await getPageContributors(pageData.relativePath) } // 或者返回待合并的值 async transformPageData(pageData, { siteConfig }) { return { contributors: await getPageContributors(pageData.relativePath) } } }
interface TransformPageContext { siteConfig: SiteConfig }

从源码注释看(src/node/siteConfig.ts),该钩子在开发与构建两种模式下渲染 Markdown 到 Vue 时都会被调用,返回的变更值会合并进页面数据——这正是它在开发模式下也能生效的原因。

结语:从配置到行为的关键路径

回顾全文,VitePress 的站点配置并非一份"写了就完事"的清单,而是一条可追踪的代码路径:defineConfig提供类型约束 →resolveUserConfig/resolveConfig完成文件加载、路径归一化与默认值填充 →resolveSiteData产出运行时站点数据 →createMarkdownRenderermarkdown选项装配解析器与插件 → 构建钩子(buildEnd/postRender/transformHead/transformHtml/transformPageData)在 SSG 流水线的各个节点介入。掌握这条链路之后,无论是排查 base 路径问题、定制 head、注入动态元数据,还是接入 PWA 与站点地图,都能在 src/node/config.ts、src/node/siteConfig.ts 与 src/node/markdown/markdown.ts 中找到对应的实现依据,从而让配置从"照抄示例"升级为"可解释、可扩展"。

  • 前端
  • 文档

【免费下载链接】vitepress

Vite & Vue powered static site generator.

项目地址:https://gitcode.com/gh_mirrors/vi/vitepress
点击查看免费下载

相关推荐

上一篇:RealSense SDK Windows 配置:从插上相机到跑通深度图的 4 个关键动作
下一篇:ntfy内存管理:Go语言垃圾回收与内存泄漏预防

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询