【VueVitepress】 根据目录自动生成 sidebar 配置

1,451 阅读2分钟

背景

在给 Vitepress 新增导航时,总需要去手动去 .vitepress/config.jssidebar 配置中去添加,特别是当创建了许多目录的结构的时候,加起来就很麻烦了。

目的

能够根据 docs 目录自动地生成 sidebar 的配置,无需再手动去维护.

分析

在执行 npm run docs:dev 之后,vitepress 会先运行 .vitepress/config.js 脚本。因此此时的运行环境是 Node,我们可以使用 Node.js 提供的文件系统模块(fs)和路径模块(path)来实现自动生成 VitePress 的 sidebar 配置。分为以下步骤:

  1. 读取 docs 目录下所有文件的路径
  2. 根据文件路径生成对应的 sidebar 配置

sidebar 的常规配置是这样的:

{
  "/rules/": [
    {
      "text": "",
      "items": [
        {
          "text": "husky",
          "link": "/rules/husky"
        },
        {
          "text": "分支管理规范",
          "link": "/rules/分支管理规范"
        }
      ],
    }
  ],
  "/algorithm/": [
    {
      "text": "",
      "items": [
        {
          "text": "array",
          "link": "/basic/array"
        }
      ],
    }
  ]

最终代码

直接复制粘贴就可以生效了。

在下面代码,通过文件系统模块(fs)和路径模块(path),找到 docs 下的所有文件,遍历这些文件,根据所需格式,去生成 sidebar 配置。

const fs = require("fs");
const path = require("path");

const docsPath = path.dirname(__dirname); // docs 目录路径
const sidebarConfig = generateSidebarConfig(docsPath);

function generateSidebarConfig(docsPath, link = '', index = 0) {
  const sidebarConfig = {};
  const files = fs.readdirSync(docsPath);

  files.forEach((filename) => {
    if (filename.startsWith(".")) return;
    const filepath = path.join(docsPath, filename);
    const stat = fs.statSync(filepath);
    // 如果是文件夹,则递归生成子级 sidebar 配置
    if (stat.isDirectory()) {
      if (index === 0) {
        const config = generateSidebarConfig(filepath, `/${filename}/`, index + 1);
        if (!sidebarConfig[`/${filename}/`]) {
          sidebarConfig[`/${filename}/`] = [config];
        }
      } else {
        if (!sidebarConfig.items) {
          sidebarConfig.items = [];
        }
        sidebarConfig.items.push(generateSidebarConfig(filepath, `${link}${filename}/`, index + 1))
      }
    } else {
      const extname = path.extname(filepath);
      const basename = path.basename(filepath, extname);
      if (filename === 'index.md' && index > 0) {
        const menuPath = path.dirname(filepath);
        const menuName = path.basename(menuPath) 
        sidebarConfig.text = menuName;
        sidebarConfig.link = link;
      }
      if (extname === ".md" && filename !== "index.md") {
        if (!sidebarConfig.items) {
          sidebarConfig.items = [];
        }
        sidebarConfig.items.push({
          text: basename,
          link: `${link}${basename}`,
        });
      }
    }
  });

  return sidebarConfig;
}

module.exports = {
  base: "/",
  themeConfig: {
    lastUpdated: "Last Updated",
    nav: [
      { text: "算法", link: "/algorithm/" },
      { text: "Github", link: "https://github.com/hugheschoi" },
    ],
    sidebar: sidebarConfig,
  },
};

注意

  1. 每个目录至少要有一个 index.md 文件,你可以在 index.md 做一些总览和介绍
  2. 如果新建了新文件夹,需要重新执行一遍,目录配置才能生效

总结

实现方式其实不难,简单来讲就是使用 Node 读取目录,根据目录得到配置对象。但是就是比较繁琐,因此我在这里实现了这一个方法,帮助大家节省宝贵的时间。