From 5550fac160614c25e8c2573e82d3f150b8505f84 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sun, 8 Mar 2026 18:28:48 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=87=E6=A1=A3=E7=9B=91=E5=90=AC?= =?UTF-8?q?=E4=B8=8E=20vitepress=20=E7=AB=9E=E6=80=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/api.ts | 112 +++++++++++++++----------------------- docs/.vitepress/config.ts | 36 +++++++++++- docs/.vitepress/init.ts | 5 ++ package.json | 2 +- tsconfig.node.json | 10 +++- 5 files changed, 93 insertions(+), 72 deletions(-) create mode 100644 docs/.vitepress/init.ts diff --git a/docs/.vitepress/api.ts b/docs/.vitepress/api.ts index 287f72d..2faba7e 100644 --- a/docs/.vitepress/api.ts +++ b/docs/.vitepress/api.ts @@ -1,59 +1,64 @@ -import fs from 'fs-extra'; -import path from 'path'; -import chokidar from 'chokidar'; +import { basename, join, resolve } from 'node:path'; import { DefaultTheme } from 'vitepress'; +import { readdir, stat, writeFile } from 'node:fs/promises'; -const apiDir = path.resolve('./docs/api'); -const sidebarConfigPath = path.resolve('./docs/.vitepress/apiSidebar.ts'); +const apiDir = resolve('./docs/api'); +const sidebarConfigPath = resolve('./docs/.vitepress/apiSidebar.ts'); const weight: Record = { 主页: 10, 函数: 5 }; -function generateSidebar(): void { +export async function generateSidebar(): Promise { const sidebar: DefaultTheme.SidebarItem[] = [ { text: '目录', link: '/api/' } ]; // 遍历 api 目录,查找 package 目录 - const packages = fs - .readdirSync(apiDir) - .filter(pkg => fs.statSync(path.join(apiDir, pkg)).isDirectory()); + const dir = await readdir(apiDir); + const packages = []; + for (const pkg of dir) { + const stats = await stat(join(apiDir, pkg)); + if (stats.isDirectory()) { + packages.push(pkg); + } + } - packages.forEach(pkg => { - const pkgPath = path.join(apiDir, pkg); - const files = fs - .readdirSync(pkgPath) - .filter(file => file.endsWith('.md')); + await Promise.all( + packages.map(async pkg => { + const pkgPath = join(apiDir, pkg); + const dir = await readdir(pkgPath); + const files = dir.filter(file => file.endsWith('.md')); - const items: DefaultTheme.SidebarItem[] = files.map(file => { - const filePath = `api/${pkg}/${file}`; - const fileName = path.basename(file, '.md'); + const items: DefaultTheme.SidebarItem[] = files.map(file => { + const filePath = `api/${pkg}/${file}`; + const fileName = basename(file, '.md'); - return { - text: - fileName === 'index' - ? '主页' - : fileName === 'functions' - ? '函数' - : fileName, - link: `/${filePath.replace(/\\/g, '/')}` // 兼容 Windows 路径 - }; - }); + return { + text: + fileName === 'index' + ? '主页' + : fileName === 'functions' + ? '函数' + : fileName, + link: `/${filePath.replace(/\\/g, '/')}` // 兼容 Windows 路径 + }; + }); - items.sort((a, b) => { - const titleA = a.text ?? ''; - const titleB = b.text ?? ''; - return (weight[titleB] ?? 0) - (weight[titleA] ?? 0); - }); + items.sort((a, b) => { + const titleA = a.text ?? ''; + const titleB = b.text ?? ''; + return (weight[titleB] ?? 0) - (weight[titleA] ?? 0); + }); - sidebar.push({ - text: pkg, - collapsed: true, - items - }); - }); + sidebar.push({ + text: pkg, + collapsed: true, + items + }); + }) + ); // 生成 sidebar.ts const sidebarContent = `import { DefaultTheme } from 'vitepress'; @@ -63,35 +68,6 @@ export default ${JSON.stringify( null, 4 )} as DefaultTheme.SidebarItem[];`; - fs.writeFileSync(sidebarConfigPath, sidebarContent); + await writeFile(sidebarConfigPath, sidebarContent); console.log('✅ Sidebar 配置已更新'); } - -// 初次运行 -generateSidebar(); - -// 监听文件变动 -chokidar - .watch(apiDir, { ignoreInitial: true }) - .on('add', filePath => { - console.log(`📄 文件新增: ${filePath}`); - generateSidebar(); - }) - .on('unlink', filePath => { - console.log(`❌ 文件删除: ${filePath}`); - generateSidebar(); - }) - .on('addDir', dirPath => { - console.log(`📁 目录新增: ${dirPath}`); - generateSidebar(); - }) - .on('unlinkDir', dirPath => { - console.log(`📁 目录删除: ${dirPath}`); - generateSidebar(); - }) - .on('raw', (event, path, details) => { - if (event === 'rename') { - console.log(`🔄 文件或文件夹重命名: ${path}`); - generateSidebar(); - } - }); diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index ff1f41e..5d101e9 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,7 +1,39 @@ -import { defineConfig } from 'vitepress'; +import { defineConfig, Plugin } from 'vitepress'; import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid'; import api from './apiSidebar'; import { join } from 'path'; +import { generateSidebar } from './api'; + +function listenSidebar(): Plugin { + return { + name: 'sidebar-listen', + configureServer(server) { + server.watcher + .on('add', filePath => { + console.log(`📄 文件新增: ${filePath}`); + generateSidebar(); + }) + .on('unlink', filePath => { + console.log(`❌ 文件删除: ${filePath}`); + generateSidebar(); + }) + .on('addDir', dirPath => { + console.log(`📁 目录新增: ${dirPath}`); + generateSidebar(); + }) + .on('unlinkDir', dirPath => { + console.log(`📁 目录删除: ${dirPath}`); + generateSidebar(); + }) + .on('raw', (event, path, _) => { + if (event === 'rename') { + console.log(`🔄 文件或文件夹重命名: ${path}`); + generateSidebar(); + } + }); + } + }; +} // https://vitepress.dev/reference/site-config export default defineConfig({ @@ -157,7 +189,7 @@ export default defineConfig({ }, vite: { // @ts-expect-error 类型错误 - plugins: [MermaidPlugin()], + plugins: [MermaidPlugin(), listenSidebar()], optimizeDeps: { include: ['mermaid'] }, diff --git a/docs/.vitepress/init.ts b/docs/.vitepress/init.ts new file mode 100644 index 0000000..902c4c0 --- /dev/null +++ b/docs/.vitepress/init.ts @@ -0,0 +1,5 @@ +import { generateSidebar } from './api'; + +(() => { + generateSidebar(); +})(); diff --git a/package.json b/package.json index aa16d59..1b73137 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build:packages": "vue-tsc --noEmit && tsx script/build-packages.ts", "build:game": "tsx script/declare.ts && vue-tsc --noEmit && tsx script/build-game.ts", "build:lib": "vue-tsc --noEmit && tsx script/build-lib.ts", - "docs:dev": "concurrently -k -n SIDEBAR,VITEPRESS -c blue,green \"tsx docs/.vitepress/api.ts\" \"vitepress dev docs\"", + "docs:dev": "tsx docs/.vitepress/init.ts && vitepress dev docs", "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs", "pack:template": "tsx script/pack-template.ts" diff --git a/tsconfig.node.json b/tsconfig.node.json index bc93b79..756a862 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -7,5 +7,13 @@ "allowSyntheticDefaultImports": true, "strict": true }, - "include": ["vite.config.ts", "script/**/*.ts", "mota.config.ts"] + "include": [ + "vite.config.ts", + "script/**/*.ts", + "docs/**/*.ts", + "docs/.vitepress/api.ts", + "docs/.vitepress/config.ts", + "docs/.vitepress/apiSidebar.ts", + "docs/.vitepress/init.ts" + ] }