Skip to content

故障排查手册

本页面整理了 VitePress 开发和构建过程中的常见错误及解决方案,帮助你快速定位和解决问题。

📋 错误代码速查表

错误关键词类型快速定位
Cannot find module依赖模块未找到错误
heap out of memory构建内存溢出错误
Failed to compile markdown构建Markdown 编译错误
Failed to resolve Vue component组件Vue 组件编译错误
Port is in use开发端口被占用
localStorage is not definedSSRlocalStorage 未定义
Hydration node mismatchSSRhydrate 错误
Failed to resolve component组件组件未注册
页面空白部署路径问题
资源 404部署静态资源加载失败

🎯 按场景排查

场景可能原因解决方案
开发服务器启动失败端口占用/依赖缺失开发服务器错误
构建失败配置错误/语法错误构建错误
页面白屏路径配置/SSR 兼容部署错误 | 运行时错误
样式不生效CSS 优先级/变量覆盖样式错误
搜索不工作配置错误/索引问题搜索功能不工作

🚨 构建错误

1. 模块未找到错误

错误信息

Error: Cannot find module 'xxx'

原因:依赖包未安装或版本不兼容。

解决方案

bash
# 清除缓存并重新安装
rm -rf node_modules package-lock.json
npm install

# 或使用 pnpm
pnpm store prune
pnpm install

2. 内存溢出错误

错误信息

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

原因:项目过大,Node.js 默认内存不足。

解决方案

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

# 或在 package.json 中配置
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=8192' vitepress build docs"
  }
}

3. Markdown 编译错误

错误信息

[vitepress] Failed to compile markdown file

原因:Markdown 语法错误或自定义容器配置问题。

解决方案

  1. 检查 Markdown 语法
  2. 检查自定义容器是否正确闭合
  3. 查看错误信息中的文件和行号
markdown
<!-- 错误示例:容器未闭合 -->
::: tip
内容...
<!-- 缺少 ::: -->

<!-- 正确示例 -->
::: tip
内容...
:::

4. Vue 组件编译错误

错误信息

[vitepress] Failed to resolve Vue component

原因:组件路径错误或组件未正确注册。

解决方案

ts
// 检查组件注册
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MyComponent from './components/MyComponent.vue'

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

⚡ 开发服务器错误

1. 端口被占用

错误信息

Port 5173 is in use, trying another one...

解决方案

bash
# 查找占用端口的进程
lsof -i :5173

# 终止进程
kill -9 <PID>

# 或指定其他端口
npm run docs:dev -- --port 3000

2. 热更新不生效

原因:文件监听数量限制或 Vite 配置问题。

解决方案

ts
// docs/.vitepress/config.ts
export default defineConfig({
  vite: {
    server: {
      watch: {
        usePolling: true,
        interval: 100
      }
    }
  }
})
bash
# Linux 增加文件监听数量
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

3. 页面白屏

原因:JavaScript 错误或组件渲染失败。

排查步骤

  1. 打开浏览器开发者工具 (F12)
  2. 查看 Console 面板中的错误信息
  3. 检查 Network 面板是否有资源加载失败

常见原因

ts
// 1. 客户端代码在 SSR 时使用了 window/document
if (typeof window !== 'undefined') {
  // 客户端代码
}

// 2. 使用 onMounted 钩子
import { onMounted } from 'vue'

onMounted(() => {
  // 这里的代码只在客户端执行
})

// 3. 使用 ClientOnly 组件
<ClientOnly>
  <YourComponent />
</ClientOnly>

📦 部署错误

1. 路径问题

错误现象:部署后资源 404,页面空白。

解决方案

ts
// docs/.vitepress/config.ts
export default defineConfig({
  // 如果部署到子路径,如 https://example.com/blog/
  base: '/blog/',
  
  // 或使用环境变量
  base: process.env.BASE_URL || '/'
})

2. 静态资源加载失败

原因:资源路径大小写不匹配或文件不存在。

解决方案

ts
// 检查图片路径
![图片](./images/hero.png)  // 确保文件名大小写一致

// 使用绝对路径
![图片](/images/hero.png)  // public 目录下的资源

3. 构建产物过大

原因:未进行代码分割或依赖未优化。

解决方案

ts
// docs/.vitepress/config.ts
export default defineConfig({
  vite: {
    build: {
      chunkSizeWarningLimit: 1000,
      rollupOptions: {
        output: {
          manualChunks: {
            'vendor': ['vue'],
            'utils': ['lodash-es']
          }
        }
      }
    }
  }
})

🔧 配置错误

1. 侧边栏配置无效

原因:路径匹配不正确。

解决方案

ts
// docs/.vitepress/config.ts
const sidebar = {
  // 注意路径前缀
  '/guide/': [
    {
      text: '入门',
      items: [
        { text: '介绍', link: '/guide/introduction' },
        // link 不需要 .md 后缀
      ]
    }
  ]
}

2. 导航栏不显示

原因:配置格式错误或路径问题。

解决方案

ts
// docs/.vitepress/config.ts
export default defineConfig({
  themeConfig: {
    nav: [
      { text: '首页', link: '/' },  // 正确
      { text: '指南', link: '/guide/' },  // 目录需要有尾部斜杠
    ]
  }
})

3. 搜索功能不工作

原因:本地搜索索引问题或 Algolia 配置错误。

解决方案

ts
// 本地搜索
export default defineConfig({
  themeConfig: {
    search: {
      provider: 'local',
      options: {
        // 确保搜索字段正确
        miniSearch: {
          searchOptions: {
            fuzzy: 0.2
          }
        }
      }
    }
  }
})

// Algolia 搜索
export default defineConfig({
  themeConfig: {
    search: {
      provider: 'algolia',
      options: {
        appId: 'YOUR_APP_ID',
        apiKey: 'YOUR_API_KEY',
        indexName: 'YOUR_INDEX_NAME'
      }
    }
  }
})

🎨 样式错误

1. 样式不生效

原因:CSS 变量覆盖位置不对或优先级问题。

解决方案

css
/* docs/.vitepress/theme/style.css */

/* 确保在 :root 和 .dark 中都定义 */
:root {
  --vp-c-brand-1: #6366f1;
}

.dark {
  --vp-c-brand-1: #a5b4fc;
}

/* 使用 !important 提高优先级(最后手段) */
.custom-class {
  color: var(--vp-c-brand-1) !important;
}

2. 深色模式样式异常

原因:只定义了浅色模式样式。

解决方案

css
/* 同时定义浅色和深色模式 */
.custom-component {
  background-color: #ffffff;
}

.dark .custom-component {
  background-color: #1e1e1e;
}

/* 或使用 CSS 变量 */
:root {
  --bg-color: #ffffff;
}

.dark {
  --bg-color: #1e1e1e;
}

.custom-component {
  background-color: var(--bg-color);
}

🐛 运行时错误

1. localStorage 未定义

错误信息

ReferenceError: localStorage is not defined

原因:在 SSR 阶段访问了浏览器 API。

解决方案

vue
<script setup>
import { ref, onMounted } from 'vue'

const data = ref(null)

// 方式 1: 使用 onMounted
onMounted(() => {
  data.value = localStorage.getItem('key')
})

// 方式 2: 检查环境
if (typeof window !== 'undefined') {
  data.value = localStorage.getItem('key')
}

// 方式 3: 使用 ClientOnly 包裹
</script>

<template>
  <ClientOnly>
    <div>{{ data }}</div>
  </ClientOnly>
</template>

2. hydrate 错误

错误信息

[Vue warn] Hydration node mismatch

原因:服务端和客户端渲染内容不一致。

解决方案

vue
<script setup>
import { ref, onMounted } from 'vue'

// 使用 onMounted 确保只在客户端渲染动态内容
const dynamicContent = ref('')
onMounted(() => {
  dynamicContent.value = '客户端内容'
})
</script>

<template>
  <!-- 静态内容保持一致 -->
  <div>{{ dynamicContent }}</div>
</template>

3. 组件未注册

错误信息

Failed to resolve component: xxx

解决方案

ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MyComponent from './components/MyComponent.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    // 全局注册组件
    app.component('MyComponent', MyComponent)
  }
}

📋 错误排查清单

遇到问题时,按以下步骤排查:

基础检查

  • [ ] Node.js 版本是否符合要求?(推荐 18.x+)
  • [ ] 依赖是否正确安装?(npm install)
  • [ ] 配置文件语法是否正确?
  • [ ] 文件路径是否正确?

开发环境

  • [ ] 端口是否被占用?
  • [ ] 是否有控制台错误?
  • [ ] 热更新是否正常?

构建部署

  • [ ] 构建命令是否正确?
  • [ ] base 路径是否配置?
  • [ ] 静态资源是否存在?
  • [ ] 环境变量是否正确?

运行时

  • [ ] 是否在 SSR 中使用了浏览器 API?
  • [ ] 组件是否正确注册?
  • [ ] 样式是否正确导入?

🔍 调试技巧

1. 启用调试模式

bash
# 启用详细日志
DEBUG=vitepress:* npm run docs:dev

# 或使用 Node.js 调试
node --inspect-brk node_modules/.bin/vitepress dev docs

2. 检查配置

ts
// docs/.vitepress/config.ts
export default defineConfig({
  // 添加自定义日志
  head: [
    ['script', {}, `
      console.log('Config loaded');
    `]
  ]
})

3. 使用 Vue DevTools

安装 Vue DevTools 浏览器扩展,检查组件状态和事件。


💬 获取帮助

如果以上方法无法解决问题:

  1. 搜索 Issue - VitePress GitHub Issues
  2. 社区讨论 - VitePress Discussions
  3. Discord 社区 - Vue.js Discord
  4. 提交 Issue - 提供复现步骤和错误信息

提交 Issue 建议

提交 Issue 时,请提供以下信息:

  • Node.js 版本 (node -v)
  • 包管理器版本 (npm/pnpm/yarn)
  • VitePress 版本
  • 最小复现示例
  • 完整错误日志

🚷 常见踩坑指南

1. base 路径配置错误

陷阱:开发时一切正常,部署后页面空白或资源 404。

ts
// ❌ 错误:部署到子目录但未配置 base
export default defineConfig({
  // 缺少 base 配置
})

// ✅ 正确:部署到 https://example.com/docs/ 时
export default defineConfig({
  base: '/docs/',
})

排查:打开浏览器 Network 面板,检查 JS/CSS 文件请求路径是否包含 base 前缀。


2. cleanUrls 与服务器不兼容

陷阱:启用 cleanUrls 后,服务器需要正确配置。

ts
// 开启 clean URLs(去掉 .html 后缀)
export default defineConfig({
  cleanUrls: true,
})

必须配置服务器

nginx
# Nginx
location / {
  try_files $uri $uri/ $uri.html /index.html;
}
apache
# Apache (.htaccess)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+\.html)$ /$1 [R=301,L]

3. frontmatter 类型错误

陷阱:VitePress 对 frontmatter 有严格的类型检查。

yaml
# ❌ 错误:layout 不是 VitePress 支持的值
---
layout: custom   # 只支持 doc | home | page
---

# ✅ 正确:自定义布局使用 frontmatter 其他字段
---
layout: page
customLayout: blog-list
---

4. 静态导入 vs 动态导入

陷阱:在 Vue 组件中静态导入大型库导致所有页面加载变慢。

vue
<!-- ❌ 错误:每个页面都会加载 lodash -->
<script setup>
import _ from 'lodash'
</script>

<!-- ✅ 正确:按需导入或动态导入 -->
<script setup>
import { debounce } from 'lodash-es'
// 或
const module = await import('some-large-module')
</script>

5. CSS 优先级问题

陷阱:自定义样式被 VitePress 默认样式覆盖。

css
/* ❌ 错误:选择器优先级不够 */
.my-container {
  padding: 20px;
}

/* ✅ 正确:提高选择器优先级 */
.vp-doc .my-container {
  padding: 20px;
}

/* ✅ 或使用 CSS 层叠层 */
@layer vp-custom {
  .my-container {
    padding: 20px;
  }
}

6. createContentLoader 数据格式

陷阱createContentLoader 返回的数据结构和预期不一致。

ts
// ❌ 错误:假设 frontmatter 字段一定存在
const posts = await createContentLoader('posts/*.md', {}).load()
posts.forEach(post => {
  console.log(post.frontmatter.title) // 可能 undefined
})

// ✅ 正确:提供类型定义和默认值
interface Post {
  title: string
  date: string
  tags?: string[]
}

const posts = await createContentLoader('posts/*.md', {
  transform(rawData): Post[] {
    return rawData.map(({ frontmatter }) => ({
      title: frontmatter.title || '未命名',
      date: frontmatter.date || '',
      tags: frontmatter.tags || []
    }))
  }
}).load()

7. SSR 水合不匹配

陷阱:服务端和客户端渲染结果不一致导致水合错误。

vue
<!-- ❌ 错误:使用 Date.now() 导致 SSR/CSR 不一致 -->
<template>
  <div>当前时间: {{ Date.now() }}</div>
</template>

<!-- ✅ 正确:在 onMounted 中使用客户端 API -->
<script setup>
import { ref, onMounted } from 'vue'
const time = ref('')
onMounted(() => {
  time.value = new Date().toLocaleString()
})
</script>
<template>
  <div>当前时间: {{ time }}</div>
</template>

8. 搜索索引过大

陷阱:文档数量多时本地搜索索引过大,影响加载性能。

ts
// ✅ 正确:排除不需要搜索的页面
// 在 markdown frontmatter 中
---
search: false
---

// 或在配置中限制
export default defineConfig({
  themeConfig: {
    search: {
      provider: 'local',
      options: {
        miniSearch: {
          options: {
            // 设置最小搜索词长度
            minQueryLength: 2,
            // 限制搜索结果数量
            maxSearchResults: 10
          }
        }
      }
    }
  }
})

9. 侧边栏自动生成陷阱

陷阱:使用 sidebar: { auto: true } 时,排序不符合预期。

ts
// ❌ auto 模式按文件名排序,可能不理想
export default defineConfig({
  themeConfig: {
    sidebar: { auto: true }
  }
})

// ✅ 使用手动配置控制顺序
// 即使目录文件很多,也建议手动配置核心页面
export default defineConfig({
  themeConfig: {
    sidebar: {
      '/guide/': [
        { text: '安装', link: '/guide/installation' },
        { text: '配置', link: '/guide/configuration' },
        { text: '路由', link: '/guide/routing' },
      ]
    }
  }
})

10. 构建时环境变量

陷阱:在构建时使用了只在开发环境有效的变量。

ts
// ❌ 错误:process.env.NODE_ENV 在 VitePress 中可能不是预期值
if (process.env.NODE_ENV === 'development') { ... }

// ✅ 正确:使用 import.meta.env
if (import.meta.env.DEV) { ... }
if (import.meta.env.PROD) { ... }

// ✅ 自定义环境变量需要 VITE_ 前缀
// .env.production
VITE_API_URL=https://api.example.com

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献