mirror of
https://github.com/motajs/template.git
synced 2026-04-12 15:11:10 +08:00
fix: 文档监听与 vitepress 竞态问题
This commit is contained in:
parent
5a1a0fee42
commit
5550fac160
@ -1,59 +1,64 @@
|
|||||||
import fs from 'fs-extra';
|
import { basename, join, resolve } from 'node:path';
|
||||||
import path from 'path';
|
|
||||||
import chokidar from 'chokidar';
|
|
||||||
import { DefaultTheme } from 'vitepress';
|
import { DefaultTheme } from 'vitepress';
|
||||||
|
import { readdir, stat, writeFile } from 'node:fs/promises';
|
||||||
|
|
||||||
const apiDir = path.resolve('./docs/api');
|
const apiDir = resolve('./docs/api');
|
||||||
const sidebarConfigPath = path.resolve('./docs/.vitepress/apiSidebar.ts');
|
const sidebarConfigPath = resolve('./docs/.vitepress/apiSidebar.ts');
|
||||||
|
|
||||||
const weight: Record<string, number> = {
|
const weight: Record<string, number> = {
|
||||||
主页: 10,
|
主页: 10,
|
||||||
函数: 5
|
函数: 5
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateSidebar(): void {
|
export async function generateSidebar(): Promise<void> {
|
||||||
const sidebar: DefaultTheme.SidebarItem[] = [
|
const sidebar: DefaultTheme.SidebarItem[] = [
|
||||||
{ text: '目录', link: '/api/' }
|
{ text: '目录', link: '/api/' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// 遍历 api 目录,查找 package 目录
|
// 遍历 api 目录,查找 package 目录
|
||||||
const packages = fs
|
const dir = await readdir(apiDir);
|
||||||
.readdirSync(apiDir)
|
const packages = [];
|
||||||
.filter(pkg => fs.statSync(path.join(apiDir, pkg)).isDirectory());
|
for (const pkg of dir) {
|
||||||
|
const stats = await stat(join(apiDir, pkg));
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
packages.push(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packages.forEach(pkg => {
|
await Promise.all(
|
||||||
const pkgPath = path.join(apiDir, pkg);
|
packages.map(async pkg => {
|
||||||
const files = fs
|
const pkgPath = join(apiDir, pkg);
|
||||||
.readdirSync(pkgPath)
|
const dir = await readdir(pkgPath);
|
||||||
.filter(file => file.endsWith('.md'));
|
const files = dir.filter(file => file.endsWith('.md'));
|
||||||
|
|
||||||
const items: DefaultTheme.SidebarItem[] = files.map(file => {
|
const items: DefaultTheme.SidebarItem[] = files.map(file => {
|
||||||
const filePath = `api/${pkg}/${file}`;
|
const filePath = `api/${pkg}/${file}`;
|
||||||
const fileName = path.basename(file, '.md');
|
const fileName = basename(file, '.md');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
text:
|
text:
|
||||||
fileName === 'index'
|
fileName === 'index'
|
||||||
? '主页'
|
? '主页'
|
||||||
: fileName === 'functions'
|
: fileName === 'functions'
|
||||||
? '函数'
|
? '函数'
|
||||||
: fileName,
|
: fileName,
|
||||||
link: `/${filePath.replace(/\\/g, '/')}` // 兼容 Windows 路径
|
link: `/${filePath.replace(/\\/g, '/')}` // 兼容 Windows 路径
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
items.sort((a, b) => {
|
items.sort((a, b) => {
|
||||||
const titleA = a.text ?? '';
|
const titleA = a.text ?? '';
|
||||||
const titleB = b.text ?? '';
|
const titleB = b.text ?? '';
|
||||||
return (weight[titleB] ?? 0) - (weight[titleA] ?? 0);
|
return (weight[titleB] ?? 0) - (weight[titleA] ?? 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
sidebar.push({
|
sidebar.push({
|
||||||
text: pkg,
|
text: pkg,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
items
|
items
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// 生成 sidebar.ts
|
// 生成 sidebar.ts
|
||||||
const sidebarContent = `import { DefaultTheme } from 'vitepress';
|
const sidebarContent = `import { DefaultTheme } from 'vitepress';
|
||||||
@ -63,35 +68,6 @@ export default ${JSON.stringify(
|
|||||||
null,
|
null,
|
||||||
4
|
4
|
||||||
)} as DefaultTheme.SidebarItem[];`;
|
)} as DefaultTheme.SidebarItem[];`;
|
||||||
fs.writeFileSync(sidebarConfigPath, sidebarContent);
|
await writeFile(sidebarConfigPath, sidebarContent);
|
||||||
console.log('✅ Sidebar 配置已更新');
|
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
@ -1,7 +1,39 @@
|
|||||||
import { defineConfig } from 'vitepress';
|
import { defineConfig, Plugin } from 'vitepress';
|
||||||
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
|
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
|
||||||
import api from './apiSidebar';
|
import api from './apiSidebar';
|
||||||
import { join } from 'path';
|
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
|
// https://vitepress.dev/reference/site-config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@ -157,7 +189,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
// @ts-expect-error 类型错误
|
// @ts-expect-error 类型错误
|
||||||
plugins: [MermaidPlugin()],
|
plugins: [MermaidPlugin(), listenSidebar()],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['mermaid']
|
include: ['mermaid']
|
||||||
},
|
},
|
||||||
|
|||||||
5
docs/.vitepress/init.ts
Normal file
5
docs/.vitepress/init.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { generateSidebar } from './api';
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
generateSidebar();
|
||||||
|
})();
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"build:packages": "vue-tsc --noEmit && tsx script/build-packages.ts",
|
"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:game": "tsx script/declare.ts && vue-tsc --noEmit && tsx script/build-game.ts",
|
||||||
"build:lib": "vue-tsc --noEmit && tsx script/build-lib.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:build": "vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs",
|
"docs:preview": "vitepress preview docs",
|
||||||
"pack:template": "tsx script/pack-template.ts"
|
"pack:template": "tsx script/pack-template.ts"
|
||||||
|
|||||||
@ -7,5 +7,13 @@
|
|||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"strict": 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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user