VitePress 集成 Mermaid 插件、dayjs 导出错误与 pnpm 依赖冲突

VitePress 进阶实战:深度解决 Mermaid 插件嵌套、dayjs 导出错误与 pnpm 依赖冲突

前言

在搭建个人技术博客时,我选择了 VitePress 作为静态站点生成器。为了实现侧边栏自动生成Mermaid 图表支持,我引入了 vitepress-sidebarvitepress-plugin-mermaid。然而,在插件嵌套的过程中,我遭遇了从“语法高亮失效”到“浏览器一片空白”的一系列深度坑位。本文将记录这一系列问题的排查与最终解决方案。


核心痛点与错误复现

1. 致命的“空白页”:dayjs 导出错误

在引入插件并尝试启动服务后,浏览器控制台报错:

Uncaught SyntaxError: The requested module '...dayjs.min.js' does not provide an export named 'default'

原因分析vitepress-sidebar 内部依赖 dayjs 处理文件日期。由于 dayjs 是 CommonJS 模块,而 Vite 运行在 ESM 环境下,在复杂的插件嵌套(withMermaid 包裹 withSidebar)中,Vite 的自动转换机制失效,导致无法识别默认导出。

2. 构建崩溃:Vue 标签解析错误

SyntaxError: Element is missing end tag. (16:24)

原因分析:VitePress 会将 Markdown 解析为 Vue 组件。如果在正文中书写了包含尖括号的类名(如 <SqlSessionFactory>)且未被代码块包裹,编译器会将其误认为未闭合的 HTML 标签。

3. pnpm 依赖隔离:无法解析依赖

Failed to resolve dependency: dayjs, mermaid, debug...

原因分析:使用 pnpm 时,依赖被严格隔离在各自的软链接中。Vite 的 optimizeDeps 尝试在根目录预构建这些插件的内部依赖时,因为根目录 node_modules 找不到它们而报错。


最终解决方案:全栈配置模板

通过多次调试,我总结出一套“插件嵌套 + 依赖提升 + Vite 修正”的组合拳。

第一步:显式安装“隐身”依赖

针对 pnpm 找不到依赖的问题,最直接的办法是将插件的内部依赖手动提升到根目录。

pnpm add dayjs mermaid @braintree/sanitize-url debug cytoscape cytoscape-cose-bilkent -D

第二步:深度修正 config.mts 配置

关键点在于:markdown 配置移至顶层,并利用 vite.optimizeDeps 强制转换模块格式。

import { defineConfig } from 'vitepress';
import { withSidebar } from 'vitepress-sidebar';
import { withMermaid } from 'vitepress-plugin-mermaid';

const vitePressConfig = {
  // 1. 顶层配置:解决 Shiki 语言加载问题
  markdown: {
    languages: ['java', 'sql', 'xml', 'yaml', 'asm', 'redis'],
    theme: 'vitesse-dark',
    lineNumbers: true
  },

  // 2. 核心修复:解决 dayjs 导出与依赖预构建
  vite: {
    optimizeDeps: {
      include: ['dayjs', 'mermaid', '@braintree/sanitize-url', 'debug', 'cytoscape']
    },
    build: {
      commonjsOptions: {
        include: [/dayjs/, /node_modules/] // 强制转换 CJS 模块
      }
    }
  },

  themeConfig: {
    nav: [
      { text: 'AI', link: '/AI/' },
      { text: '数据', link: '/数据/' }
    ],
    outline: { level: [2, 6], label: '页面导航' }, //
    search: { provider: 'local' } //
  }
};

// 3. 插件嵌套:Mermaid 包裹 Sidebar
export default withMermaid(
  withSidebar(vitePressConfig as any, [
    { scanStartPath: 'AI', resolvePath: '/AI/', collapsed: true },
    { scanStartPath: '数据', resolvePath: '/数据/', collapsed: true }
  ])
);

第三步:清理缓存(救命良药)

每次修改完插件逻辑或依赖后,必须执行清理操作,否则旧的错误 ES Module 缓存会持续干扰。

# 删除 Vite 预构建缓存
rm -rf node_modules/.vite
# 删除 VitePress 运行缓存
rm -rf .vitepress/cache


避坑

  1. 反引号包裹一切技术名词:在 Markdown 中,任何包含 <> 的代码片段(即使是类名)都必须放在 ` 内,防止 Vue 编译器解析报错。
  2. 配置层级敏感:VitePress 的 markdown 配置绝不能写在 themeConfig 里,否则所有自定义语言高亮都会失效。
  3. 重视 pnpm 报错:当看到 Failed to resolve dependency 时,不要犹豫,直接 pnpm add 该依赖到开发环境。
  4. 插件嵌套顺序:经验证,withMermaid(withSidebar(config)) 是目前最稳定的写法。

posted on 2026-01-21 01:44  滚动的蛋  阅读(0)  评论(0)    收藏  举报

导航