Files
2026-06-19 14:45:07 +08:00

101 lines
2.8 KiB
JavaScript

// 构建前将 posts/ 目录处理为静态数据
// 1. 复制图片等静态文件到 public/posts/
// 2. 生成 posts-data.json 供前端直接导入
import { cpSync, existsSync, rmSync, readdirSync, statSync, readFileSync, mkdirSync, writeFileSync } from 'fs'
import { join, dirname, relative } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const root = join(__dirname, '..')
const src = join(root, 'posts')
const dst = join(root, 'public', 'posts')
// 1. 复制静态文件到 public/posts/
if (existsSync(dst)) {
rmSync(dst, { recursive: true, force: true })
}
cpSync(src, dst, {
recursive: true,
filter: (srcPath) => !srcPath.endsWith('.md')
})
console.log('已同步 posts 静态文件到 public/posts/')
// 2. 扫描 posts/ 生成数据清单
function scanDir(dir) {
const entries = readdirSync(dir)
const result = { dirs: [], files: [] }
for (const name of entries) {
if (name.startsWith('.')) continue
const full = join(dir, name)
const st = statSync(full)
if (st.isDirectory()) {
const children = scanDir(full)
// 跳过空目录
if (children.dirs.length === 0 && children.files.length === 0) continue
result.dirs.push({ name, children })
} else if (name.endsWith('.md')) {
const relPath = relative(src, full).replace(/\\/g, '/').replace(/\.md$/, '')
const content = readFileSync(full, 'utf-8')
result.files.push({ name: name.replace('.md', ''), path: relPath, content })
}
}
// 排序:文件夹在前,文件在后,各自字母排序
result.dirs.sort((a, b) => a.name.localeCompare(b.name))
result.files.sort((a, b) => a.name.localeCompare(b.name))
return result
}
function buildTree(scanResult) {
const items = []
for (const dir of scanResult.dirs) {
items.push({ type: 'category', name: dir.name, children: buildTree(dir.children) })
}
for (const file of scanResult.files) {
items.push({ type: 'post', name: file.name, path: file.path })
}
return items
}
function buildContentMap(scanResult, map = {}) {
for (const file of scanResult.files) {
map[file.path] = file.content
}
for (const dir of scanResult.dirs) {
buildContentMap(dir.children, map)
}
return map
}
function getAllPaths(scanResult, paths = []) {
for (const file of scanResult.files) {
paths.push(file.path)
}
for (const dir of scanResult.dirs) {
getAllPaths(dir.children, paths)
}
return paths
}
const scanResult = scanDir(src)
const data = {
tree: buildTree(scanResult),
contentMap: buildContentMap(scanResult),
paths: getAllPaths(scanResult)
}
const outDir = join(root, 'src', 'generated')
mkdirSync(outDir, { recursive: true })
writeFileSync(join(outDir, 'posts-data.json'), JSON.stringify(data))
console.log(`已生成 posts-data.json (${data.paths.length} 篇文章)`)