当我在使用 vitepress 来构建我的 blog 的时候,我发现新版的 vitepress 侧边栏变成需要自己手动去配置的了,文章或者目录一多就特别麻烦
图里的是 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)
}
那接下来就要开始写递归来遍历文件了,那么就会有两种选择
- 如果是文件,那么就不用继续递归
- 如果是文件夹那么就生成一个数组继续递归直到全部遍历完
那我们的函数就需要接受三个参数
- 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/'),
},
代码写完了我们来测试实际效果,下图是我使用的实际结果,但是现在我还没有找到一个配置热更新的方法,有思路的可以提供参考一下