Files
SiMengWebSite_Notes/docs/.vuepress/plugins/enrichBlogReadingTime.ts

62 lines
1.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<void> {
const tempFile = app.dir.temp('internal/blogData.js')
if (!fs.existsSync(tempFile)) return
let blogPostData: Record<string, unknown>[]
try {
const url = `${pathToFileURL(tempFile).href}?t=${Date.now()}`
const mod = await import(url) as { blogPostData: Record<string, unknown>[] }
blogPostData = mod.blogPostData.map(p => ({ ...p }))
}
catch {
return
}
const byPath = new Map<string, { minutes: number; words: number }>()
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)
},
})
}