import fs from 'node:fs' import { pathToFileURL } from 'node:url' import type { App, PluginFunction } from 'vuepress' const HMR_TAIL = `if (import.meta.webpackHot) { import.meta.webpackHot.accept() if (__VUE_HMR_RUNTIME__.updateBlogPostData) { __VUE_HMR_RUNTIME__.updateBlogPostData(blogPostData) } } if (import.meta.hot) { import.meta.hot.accept(({ blogPostData }) => { __VUE_HMR_RUNTIME__.updateBlogPostData(blogPostData) }) } ` async function enrichBlogData(app: App): Promise { const tempFile = app.dir.temp('internal/blogData.js') if (!fs.existsSync(tempFile)) return let blogPostData: Record[] try { const url = `${pathToFileURL(tempFile).href}?t=${Date.now()}` const mod = await import(url) as { blogPostData: Record[] } blogPostData = mod.blogPostData.map(p => ({ ...p })) } catch { return } const byPath = new Map() for (const page of app.pages) { const rt = page.data.readingTime as { minutes: number; words: number } | undefined if (rt && typeof rt.words === 'number') byPath.set(page.path, rt) } for (const post of blogPostData) { const rt = byPath.get(post.path as string) if (rt) post.readingTime = rt } await app.writeTemp( 'internal/blogData.js', `export const blogPostData = ${JSON.stringify(blogPostData)}\n\n${HMR_TAIL}\n`, ) } /** * 在主题写入 blogData 之后,把各页的 readingTime(字数、分钟)并入博客列表数据, * 供自定义 VPPostItem 在 /blog/ 列表展示。 */ export function enrichBlogReadingTimePlugin(): PluginFunction { return () => ({ name: 'enrich-blog-reading-time', onPrepared: async (app: App) => { await enrichBlogData(app) }, }) }