Merge pull request #155 from Ri-Nai/feat/optimize-sidebar

feat(vitepress): 重构导航与侧边栏生成脚本并修复错误
This commit is contained in:
荷雨头上插着薄荷🍀 2025-10-18 04:04:04 +08:00 committed by GitHub
commit 8f44b33488
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,8 +1,10 @@
import fs from 'node:fs' import fs from 'node:fs'
import path from 'node:path' import path from 'node:path'
import type { DefaultTheme } from 'vitepress'
export type SidebarItem = { text: string; link?: string; items?: SidebarItem[] } export type SidebarItem = DefaultTheme.SidebarItem
export type Sidebar = Record<string, SidebarItem[]> export type NavItem = DefaultTheme.NavItem
export type Sidebar = DefaultTheme.Sidebar
const DOC_EXT = ['.md'] const DOC_EXT = ['.md']
const EXCLUDED_DIRS = new Set([ const EXCLUDED_DIRS = new Set([
@ -10,6 +12,8 @@ const EXCLUDED_DIRS = new Set([
'.github', '.github',
'.vitepress', '.vitepress',
'node_modules', 'node_modules',
'images',
'docker_support',
'public', 'public',
'docs', 'docs',
'images', 'images',
@ -40,9 +44,13 @@ export function generateNavAndSidebar(rootDir: string) {
.filter((e) => !EXCLUDED_DIRS.has(e) && !e.startsWith('.')) .filter((e) => !EXCLUDED_DIRS.has(e) && !e.startsWith('.'))
sections.sort(sortByPinyinOrName) sections.sort(sortByPinyinOrName)
const nav: { text: string; link: string }[] = [] const nav: NavItem[] = []
const sidebar: Sidebar = {} const sidebar: Sidebar = {}
// This is the item type we generate from files. It has a required text and link.
// It is compatible with both NavItem and SidebarItem.
type LinkItem = { text: string; link: string }
for (const dir of sections) { for (const dir of sections) {
const abs = path.join(rootDir, dir) const abs = path.join(rootDir, dir)
const files = fs const files = fs
@ -50,27 +58,40 @@ export function generateNavAndSidebar(rootDir: string) {
.filter((f) => isMarkdown(path.join(abs, f))) .filter((f) => isMarkdown(path.join(abs, f)))
.sort(sortByPinyinOrName) .sort(sortByPinyinOrName)
// Build sidebar for this section const items: LinkItem[] = files.map((f) => ({
const items: SidebarItem[] = files.map((f) => ({
text: titleFromName(f), text: titleFromName(f),
link: `/${encodeURI(dir)}/${encodeURI(f)}`, link: `/${encodeURI(dir)}/${encodeURI(f)}`,
})) }))
// Find README.md、readme.md、index.md
const readme = ['README.md', 'readme.md', 'index.md'].find((n) => fs.existsSync(path.join(abs, n)))
if (items.length > 0) { if (items.length > 0) {
const readme = ['README.md', 'readme.md', 'index.md'].find((n) =>
fs.existsSync(path.join(abs, n)),
)
const readmeURI = readme ? `/${encodeURI(dir)}/${encodeURI(readme)}` : undefined
let sectionLink: string
let sectionItems: LinkItem[]
if (readmeURI) {
sectionLink = readmeURI
sectionItems = items.filter((i) => i.link !== readmeURI)
} else {
sectionLink = items[0].link!
sectionItems = items.slice(1)
}
sidebar[`/${dir}/`] = [ sidebar[`/${dir}/`] = [
{ {
text: dir, text: dir,
items, link: sectionLink,
items: sectionItems,
}, },
] ]
if (readme) {
nav.push({ text: dir, link: `/${encodeURI(dir)}/${encodeURI(readme)}` }) nav.push({
} else { text: dir,
nav.push({ text: dir, link: items[0].link! }) link: sectionLink,
} })
} else { } else {
nav.push({ text: dir, link: `/${encodeURI(dir)}/` }) nav.push({ text: dir, link: `/${encodeURI(dir)}/` })
} }