给你写一个vitepress自动生成侧边栏的工具

703 阅读2分钟

当我在使用 vitepress 来构建我的 blog 的时候,我发现新版的 vitepress 侧边栏变成需要自己手动去配置的了,文章或者目录一多就特别麻烦

vue3.png

图里的是 vue3 官方文档的配置,要林林总总写好多,所以我们来用 Node 写一个自动生成侧边栏的代码

第一步先定义我们的白名单,把index.md.vitepress这两个文件给去掉,这两个文件不是我们要遍历的文件

// 文件根目录
const DIR_PATH = resolve(__dirname, '../')
// 白名单,过滤不是文章的文件和文件夹
const WHITE_LIST = ['index.md', '.vitepress']

第二步要定义一个函数过滤一下白名单里的文件或者文件夹,然后取到第一级目录下的文件或者文件夹,定义一个intersections方法来取一下差值

// 文件根目录
const DIR_PATH = resolve(__dirname, '../')
// 白名单,过滤不是文章的文件和文件夹
const WHITE_LIST = ['index.md', '.vitepress']

// 判断是否是文件夹
const isDirectory = (path: string): boolean => fs.lstatSync(path).isDirectory()

// 取差值
const intersections = (arr1: , arr2: ): => Array.from(new Set(arr1.filter((item) => !new Set(arr2).has(item))))

// 我们把方法导出直接使用
export default (pathname) => {
  // 获取pathname的路径
  const dirPath = resolve(DIR_PATH, pathname)
  // 读取pathname下的所有文件或者文件夹
  const files = fs.readdirSync(dirPath)
  // 过滤掉
  const items = intersections(files, WHITE_LIST)
  // getList函数后面会讲到
  return getList(items, dirPath, pathname)
}

那接下来就要开始写递归来遍历文件了,那么就会有两种选择

  1. 如果是文件,那么就不用继续递归
  2. 如果是文件夹那么就生成一个数组继续递归直到全部遍历完

那我们的函数就需要接受三个参数

  • params 是我们要遍历的文件夹数组
  • path 是我们的文件目录,在生成侧边栏数组的的时候需要用到这个文件的具体位置,在遍历过程中他一直是上一级文件夹的地址
  • pathname 是我们在拼接 link 字段使用到的
function getList(params, path, pathname) {
  // 存放结果
  const res = []
  // 开始遍历params
  for (let file in params) {
    // 拼接目录
    const dir = resolve(path, params[i])
    // 判断是否是文件夹
    const isDir = isDirectory(dir)
    if (isDir) {
      // 如果是文件夹,读取之后作为下一次递归参数
      const files = fs.readdirSync(dir)
      res.push({
        text: params[file],
        collapsible: true,
        items: getList(files, dir, `${pathname}/${params[file]}`),
      })
    } else {
      // 获取名字
      const name = params[file].split('.')[0]
      res.push({
        text: name,
        link: `${pathname}/${name}`,
      })
    }
  }
  return res
}

ok,到此结束,将上面代码合起来就是我们最终想要的

然后在我们的 sidebar 属性上就直接可以使用了


import setSideBar from "./setSideBar"


sidebar: {
     '/articles/': setSideBar('articles'),
     '/wiki/': setSideBar('wiki/'),
},

代码写完了我们来测试实际效果,下图是我使用的实际结果,但是现在我还没有找到一个配置热更新的方法,有思路的可以提供参考一下

res.png