From e677d89104e66a64157330b2e97f47a227c4236a Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Mon, 8 Jul 2024 02:37:34 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20=E5=8D=9A=E5=AE=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/plugin-blog-data/package.json | 1 + theme/src/node/prepare/prepareBlogData.ts | 92 +++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 theme/src/node/prepare/prepareBlogData.ts diff --git a/plugins/plugin-blog-data/package.json b/plugins/plugin-blog-data/package.json index 00042690..57212cc8 100644 --- a/plugins/plugin-blog-data/package.json +++ b/plugins/plugin-blog-data/package.json @@ -2,6 +2,7 @@ "name": "@vuepress-plume/plugin-blog-data", "type": "module", "version": "1.0.0-rc.72", + "private": "true", "description": "The Plugin for VuePress 2 - blog data", "author": "pengzhanbo ", "license": "MIT", diff --git a/theme/src/node/prepare/prepareBlogData.ts b/theme/src/node/prepare/prepareBlogData.ts new file mode 100644 index 00000000..9e56de26 --- /dev/null +++ b/theme/src/node/prepare/prepareBlogData.ts @@ -0,0 +1,92 @@ +import type { App, Page } from 'vuepress/core' +import { createFilter } from 'create-filter' +import { removeLeadingSlash } from '@vuepress/helper' +import { logger, normalizePath, resolveContent, writeTemp } from '../utils/index.js' +import type { + PlumeThemeBlogPostData, + PlumeThemeBlogPostItem, + PlumeThemeEncrypt, + PlumeThemeLocaleOptions, + PlumeThemePageData, + PlumeThemePostFrontmatter, +} from '../../shared/index.js' +import { resolveNotesOptions } from '../config/index.js' +import { isEncryptPage } from './prepareEncrypt.js' + +const HEADING_RE = /]*>.*?<\/h\1>/gi +const EXCERPT_SPLIT = '' + +function getTimestamp(time: Date): number { + return new Date(time).getTime() +} + +export async function preparedBlogData( + app: App, + localeOptions: PlumeThemeLocaleOptions, + encrypt?: PlumeThemeEncrypt, +): Promise { + const start = performance.now() + + const blog = localeOptions.blog || {} + const notesList = resolveNotesOptions(localeOptions) + const notesDirList = notesList + .map(notes => removeLeadingSlash(normalizePath(`${notes.dir}/**`))) + .filter(Boolean) + + const filter = createFilter( + blog.include ?? ['**/*.md'], + [ + '**/{README,readme,index}.md', + '.vuepress/', + 'node_modules/', + ...(blog.exclude ?? []), + ...notesDirList, + ].filter(Boolean), + { resolve: false }, + ) + + const pages = app.pages.filter(page => + page.filePathRelative + && filter(page.filePathRelative) + && page.frontmatter.draft !== true, + ).sort((prev, next) => + getTimestamp((prev.frontmatter.createTime as Date) || prev.date) + < getTimestamp(next.frontmatter.createTime as Date || next.date) + ? 1 + : -1, + ) as Page[] + + const blogData: PlumeThemeBlogPostData = pages.map((page) => { + page.data.isBlogPost = true + + const tags = page.frontmatter.tags + const data: PlumeThemeBlogPostItem = { + path: page.path, + title: page.title, + categoryList: page.data.categoryList, + tags, + sticky: page.frontmatter.sticky, + createTime: page.data.frontmatter.createTime!, + lang: page.lang, + excerpt: '', + } + + isEncryptPage(page, encrypt) && (data.encrypt = true) + + if (page.contentRendered.includes(EXCERPT_SPLIT)) { + const contents = page.contentRendered.split(EXCERPT_SPLIT) + let excerpt = contents[0] + // 删除摘要中的标题 + excerpt = excerpt.replace(HEADING_RE, '') + data.excerpt = excerpt + } + + return data + }) + + const content = resolveContent(app, { name: 'blogPostData', content: blogData }) + await writeTemp(app, 'internal/blogData.js', content) + + if (app.env.isDebug) + logger.info(`prepare blog data time spent: ${(performance.now() - start).toFixed(2)}ms`) +}