【VitePress】新增md文件后主动更新侧边栏导航

海哥  论坛元老 | 2025-4-13 19:08:36 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1572|帖子 1572|积分 4716

说在前面

   

  • 操作系统:windows11
  • node版本:v18.19.0
  • npm版本:10.2.3
  • vitepress版本:1.6.3
  • 完备代码:github
  先看结果



  • 模板用的就是官方主题


代码结构


具体说明

侧边栏格式



  • 通常,侧边栏定义在config.mts中
    1. export default {
    2.   themeConfig: {
    3.     sidebar: [
    4.       {
    5.         text: 'Guide',
    6.         items: [
    7.           { text: 'Introduction', link: '/introduction' },
    8.           { text: 'Getting Started', link: '/getting-started' },
    9.           ...
    10.         ]
    11.       }
    12.     ]
    13.   }
    14. }
    复制代码
    例如上述代码定义了这样子的侧边栏:

  • 而如今,我们需要根据目录内容,主动天生一个侧边栏
utils



  • 在该目录下,我们实现了一个脚本,用于主动天生侧边栏内容
    1. import FastGlob from 'fast-glob';
    2. const { glob } = FastGlob
    3. import fs from 'fs/promises';
    4. import path from 'path';
    5. import type { DefaultTheme } from 'vitepress';
    6. import chokidar from 'chokidar';
    7. type SidebarConfig = Record<string, DefaultTheme.SidebarItem[]>;
    8. export async function generateAutoSidebar(): Promise<SidebarConfig> {
    9.     const basePath = path.join(process.cwd(), 'doc/reviews');
    10.     const branches = await glob('*/', {
    11.         cwd: basePath,
    12.         onlyDirectories: true,
    13.         deep: 1
    14.     });
    15.     const sidebar: DefaultTheme.SidebarItem[] = [];
    16.     for (const branchDir of branches) {
    17.         const branchName = branchDir.replace(/\/$/, '');
    18.         const mdFiles = await glob(`${branchDir}/*.md`, {
    19.             cwd: basePath,
    20.             ignore: ['**/_*.md']
    21.         });
    22.         const items: DefaultTheme.SidebarItem[] = mdFiles
    23.             .map(file => {
    24.                 const fileName = path.basename(file, '.md');
    25.                 return {
    26.                     text: `${fileName}.md`,
    27.                     link: `/reviews/${branchDir}/${fileName}`
    28.                 };
    29.             })
    30.             .sort((a, b) => {
    31.                 const numA = parseInt(a.text.match(/\d+/)?.[0] || '0');
    32.                 const numB = parseInt(b.text.match(/\d+/)?.[0] || '0');
    33.                 return numA - numB;
    34.             });
    35.         sidebar.push({
    36.             text: branchName,
    37.             collapsed: false,
    38.             items
    39.         });
    40.     }
    41.     return { '/reviews/': sidebar };
    42. }
    43. export async function writeSidebarConfig(): Promise<void> {
    44.     const sidebarConfig = await generateAutoSidebar();
    45.     const configContent = `// Auto-generated sidebar config
    46. import type { DefaultTheme } from 'vitepress';
    47. export const sidebarConfig: DefaultTheme.Config['sidebar'] = ${JSON.stringify(sidebarConfig, null, 2)};
    48. `;
    49.     var p = path.join(process.cwd(), 'doc/.vitepress/sidebar.generated.ts')
    50.     await fs.writeFile(
    51.         p,
    52.         configContent
    53.     );
    54. }
    55. writeSidebarConfig()
    复制代码
  • 通过执行tsx doc/.vitepress/utils/generateSidebar.ts --watch,将在./doc/.vitepress/目录下主动天生sidebar.generate.ts文件,以上述reviews文件夹中内容为例,天生的内容为:
    1. // Auto-generated sidebar config
    2. import type { DefaultTheme } from 'vitepress';
    3. export const sidebarConfig: DefaultTheme.Config['sidebar'] = {
    4.   "/reviews/": [
    5.     {
    6.       "text": "aaa",
    7.       "collapsed": false,
    8.       "items": [
    9.         {
    10.           "text": "1.md",
    11.           "link": "/reviews/aaa/1"
    12.         },
    13.         {
    14.           "text": "2.md",
    15.           "link": "/reviews/aaa/2"
    16.         }
    17.       ]
    18.     },
    19.     {
    20.       "text": "bbb",
    21.       "collapsed": false,
    22.       "items": [
    23.         {
    24.           "text": "1.md",
    25.           "link": "/reviews/bbb/1"
    26.         }
    27.       ]
    28.     }
    29.   ]
    30. };
    复制代码
  • 而后,在我们的config.mts中引用即可
    1. import { defineConfig } from 'vitepress'
    2. import { sidebarConfig } from './sidebar.generated.js';
    3. // https://vitepress.dev/reference/site-config
    4. export default defineConfig({
    5.   title: "coding",
    6.   description: "code review helper",
    7.   themeConfig: {
    8.     // https://vitepress.dev/reference/default-theme-config
    9.     nav: [
    10.       { text: 'Home', link: '/' },
    11.       { text: 'Reviews', link: '/reviews' }
    12.     ],
    13.     sidebar: sidebarConfig,
    14.   },
    15.   async buildEnd() {
    16.     const { writeSidebarConfig } = await import('./utils/generateSidebar.js');
    17.     await writeSidebarConfig();
    18.   }
    19. })
    复制代码
监听文件变化



  • 在utils/generateSidebar.ts最后添加这一段,监控该目录下的文件变化,当有变化时,会主动调用writeSidebarConfig重新天生侧边栏内容
    1. // 开发模式文件监听
    2. if (process.env.NODE_ENV === 'development' || process.argv.includes('--watch')) {
    3.     const watcher = chokidar.watch('doc/reviews/**/*.md', {
    4.         ignored: /(^|[/\\])\../,
    5.         persistent: true
    6.     });
    7.     watcher
    8.         .on('add', () => writeSidebarConfig())
    9.         .on('unlink', () => writeSidebarConfig());
    10.     process.stdin.resume();
    11. }
    复制代码
使用pm2管理监听进程



  • 发起在linux下使用,windows下有问题
  • 安装
    1. npm install -D pm2
    复制代码
  • 新建ecosystem.config.js
    1. module.exports = {
    2.     apps: [
    3.         {
    4.             name: 'vitepress',
    5.             script: 'npm',
    6.             args: 'run docs:dev',
    7.             watch: ['doc/.vitepress/sidebar.generated.ts']
    8.         },
    9.         {
    10.             name: 'sidebar-watcher',
    11.             script: 'npm',
    12.             args: 'run dev:sidebar',
    13.             watch: false
    14.         }
    15.     ]
    16. };
    复制代码
  • 修改package.json
    1. {
    2.   "scripts": {
    3.     "start": "pm2 start eco.config.js",
    4.     "stop": "pm2 stop eco.config.js",
    5.     "docs:dev": "vitepress dev doc",
    6.     "docs:build": "vitepress build doc",
    7.     "docs:preview": "vitepress preview doc",
    8.     "docs:sidebar": "tsx doc/.vitepress/utils/generateSidebar.ts --watch"
    9.   },
    10.   "devDependencies": {
    11.     // ...
    12.   }
    13. }
    复制代码
  • 运行
    1. npm run start
    复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表