import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 路径配置 const NOTES_SOURCE_PATH = path.join(__dirname, '../public/mengyanote'); const OUTPUT_PATH = path.join(__dirname, '../src/data'); // 文件节点类型 const NODE_TYPES = { FOLDER: 'folder', FILE: 'file' }; // 检查是否为Markdown文件 function isMarkdownFile(filename) { return filename.toLowerCase().endsWith('.md'); } // 检查是否应该忽略的文件/文件夹 function shouldIgnore(name) { const ignoredItems = ['.obsidian', '.trash', '.git', 'node_modules']; return ignoredItems.includes(name) || name.startsWith('.'); } // 创建文件树节点 function createNode(name, type, path, children = []) { return { id: path, name, type, path, children, isExpanded: false }; } // 递归读取目录结构 function readDirectoryTree(dirPath, basePath = NOTES_SOURCE_PATH) { try { const items = fs.readdirSync(dirPath, { withFileTypes: true }); const children = []; for (const item of items) { if (shouldIgnore(item.name)) { continue; } const itemPath = path.join(dirPath, item.name); const relativePath = path.relative(basePath, itemPath).replace(/\\/g, '/'); if (item.isDirectory()) { const subChildren = readDirectoryTree(itemPath, basePath); if (subChildren.length > 0) { children.push(createNode(item.name, NODE_TYPES.FOLDER, relativePath, subChildren)); } } else if (isMarkdownFile(item.name)) { children.push(createNode(item.name, NODE_TYPES.FILE, relativePath)); } } // 排序:文件夹在前,文件在后,同类型按名称排序 children.sort((a, b) => { if (a.type !== b.type) { return a.type === NODE_TYPES.FOLDER ? -1 : 1; } return a.name.localeCompare(b.name, 'zh-CN'); }); return children; } catch (error) { console.error('Error reading directory:', error); return []; } } // 读取所有Markdown文件内容 function readAllMarkdownFiles(dirPath, basePath = NOTES_SOURCE_PATH, fileContents = {}) { try { const items = fs.readdirSync(dirPath, { withFileTypes: true }); for (const item of items) { if (shouldIgnore(item.name)) { continue; } const itemPath = path.join(dirPath, item.name); const relativePath = path.relative(basePath, itemPath).replace(/\\/g, '/'); if (item.isDirectory()) { readAllMarkdownFiles(itemPath, basePath, fileContents); } else if (isMarkdownFile(item.name)) { try { const content = fs.readFileSync(itemPath, 'utf-8'); fileContents[relativePath] = content; console.log(`✓ 读取文件: ${relativePath}`); } catch (error) { console.error(`✗ 读取文件失败: ${relativePath}`, error.message); } } } return fileContents; } catch (error) { console.error('Error reading markdown files:', error); return fileContents; } } // 生成数据文件 function generateData() { console.log('🚀 开始生成静态数据...'); // 检查源目录是否存在 if (!fs.existsSync(NOTES_SOURCE_PATH)) { console.error(`❌ 源目录不存在: ${NOTES_SOURCE_PATH}`); process.exit(1); } // 创建输出目录 if (!fs.existsSync(OUTPUT_PATH)) { fs.mkdirSync(OUTPUT_PATH, { recursive: true }); } console.log('📁 读取目录结构...'); const directoryTree = readDirectoryTree(NOTES_SOURCE_PATH); console.log('📄 读取Markdown文件内容...'); const fileContents = readAllMarkdownFiles(NOTES_SOURCE_PATH); // 生成目录树文件 const treeOutputPath = path.join(OUTPUT_PATH, 'directoryTree.json'); fs.writeFileSync(treeOutputPath, JSON.stringify(directoryTree, null, 2), 'utf-8'); console.log(`✓ 目录树已生成: ${treeOutputPath}`); // 生成文件内容文件 const contentOutputPath = path.join(OUTPUT_PATH, 'fileContents.json'); fs.writeFileSync(contentOutputPath, JSON.stringify(fileContents, null, 2), 'utf-8'); console.log(`✓ 文件内容已生成: ${contentOutputPath}`); // 生成统计信息 const stats = { totalFiles: Object.keys(fileContents).length, totalFolders: countFolders(directoryTree), generatedAt: new Date().toISOString(), sourceDirectory: NOTES_SOURCE_PATH }; const statsOutputPath = path.join(OUTPUT_PATH, 'stats.json'); fs.writeFileSync(statsOutputPath, JSON.stringify(stats, null, 2), 'utf-8'); console.log(`✓ 统计信息已生成: ${statsOutputPath}`); console.log('🎉 数据生成完成!'); console.log(`📊 统计信息:`); console.log(` - 文件数量: ${stats.totalFiles}`); console.log(` - 文件夹数量: ${stats.totalFolders}`); console.log(` - 生成时间: ${stats.generatedAt}`); } // 计算文件夹数量 function countFolders(nodes) { let count = 0; for (const node of nodes) { if (node.type === NODE_TYPES.FOLDER) { count++; if (node.children && node.children.length > 0) { count += countFolders(node.children); } } } return count; } // 执行生成 generateData();