init
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
// 构建前将 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} 篇文章)`)
|
||||
@@ -0,0 +1,20 @@
|
||||
import sharp from 'sharp'
|
||||
import { join, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const rootDir = join(__dirname, '..')
|
||||
const svgPath = join(rootDir, 'public', 'pwa-icon.svg')
|
||||
|
||||
async function generate() {
|
||||
const sizes = [192, 512]
|
||||
for (const size of sizes) {
|
||||
await sharp(svgPath)
|
||||
.resize(size, size)
|
||||
.png()
|
||||
.toFile(join(rootDir, 'public', `pwa-${size}x${size}.png`))
|
||||
console.log(`Generated pwa-${size}x${size}.png`)
|
||||
}
|
||||
}
|
||||
|
||||
generate().catch(console.error)
|
||||
Reference in New Issue
Block a user