背景
在给 Vitepress 新增导航时,总需要去手动去 .vitepress/config.js 的 sidebar 配置中去添加,特别是当创建了许多目录的结构的时候,加起来就很麻烦了。
目的
能够根据 docs 目录自动地生成 sidebar 的配置,无需再手动去维护.
分析
在执行 npm run docs:dev 之后,vitepress 会先运行 .vitepress/config.js 脚本。因此此时的运行环境是 Node,我们可以使用 Node.js 提供的文件系统模块(fs)和路径模块(path)来实现自动生成 VitePress 的 sidebar 配置。分为以下步骤:
- 读取 docs 目录下所有文件的路径
- 根据文件路径生成对应的 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,
},
};
注意
- 每个目录至少要有一个
index.md文件,你可以在index.md做一些总览和介绍 - 如果新建了新文件夹,需要重新执行一遍,目录配置才能生效
总结
实现方式其实不难,简单来讲就是使用 Node 读取目录,根据目录得到配置对象。但是就是比较繁琐,因此我在这里实现了这一个方法,帮助大家节省宝贵的时间。