diff --git a/docs/.vuepress/theme.ts b/docs/.vuepress/theme.ts index 888bd636..ad061289 100644 --- a/docs/.vuepress/theme.ts +++ b/docs/.vuepress/theme.ts @@ -6,7 +6,7 @@ export const theme: Theme = plumeTheme({ hostname: process.env.SITE_HOST || 'https://plume.pengzhanbo.cn', plugins: { - shiki: { twoslash: true }, + shiki: { twoslash: true, lineNumbers: 10 }, markdownEnhance: { demo: true, diff --git a/theme/src/node/autoFrontmatter/generator.ts b/theme/src/node/autoFrontmatter/generator.ts index 6c5fbebd..ef4d2bf4 100644 --- a/theme/src/node/autoFrontmatter/generator.ts +++ b/theme/src/node/autoFrontmatter/generator.ts @@ -26,8 +26,6 @@ export interface Generate { } let generate: Generate | null = null -let generated = false -const whenGenerated: (() => void)[] = [] export function initAutoFrontmatter( localeOptions: PlumeThemeLocaleOptions, @@ -64,16 +62,11 @@ export function initAutoFrontmatter( export async function generateAutoFrontmatter(app: App) { if (!generate) return - generated = false const markdownList = await readMarkdownList(app.dir.source(), generate.globFilter) await promiseParallel( markdownList.map(file => () => generator(file)), 64, ) - - generated = true - whenGenerated.forEach(resolve => resolve()) - whenGenerated.length = 0 } export async function watchAutoFrontmatter(app: App, watchers: any[], enable?: () => boolean) { @@ -132,12 +125,3 @@ async function generator(file: AutoFrontmatterMarkdownFile): Promise { console.error(e) } } - -export function waitForAutoFrontmatter() { - return new Promise((resolve) => { - if (generate && !generated) - whenGenerated.push(resolve) - else - resolve() - }) -} diff --git a/theme/src/node/loadConfig/loader.ts b/theme/src/node/loadConfig/loader.ts index c8697c8a..d698b46b 100644 --- a/theme/src/node/loadConfig/loader.ts +++ b/theme/src/node/loadConfig/loader.ts @@ -65,13 +65,12 @@ export async function initConfigLoader( loader.loaded = true loader.dependencies = [...dependencies] updateResolvedConfig(app, config) - runChangeEvents() loader.whenLoaded.forEach(fn => fn(loader!.resolvedConfig)) loader.whenLoaded = [] } -export function watchConfigFile(app: App, watchers: any[]) { +export function watchConfigFile(app: App, watchers: any[], onChange: ChangeEvent) { if (!loader || !loader.configFile) return @@ -82,6 +81,8 @@ export function watchConfigFile(app: App, watchers: any[]) { addDependencies(watcher) + onConfigChange(onChange) + watcher.on('change', async () => { if (loader) { loader.loaded = false @@ -121,7 +122,7 @@ export function waitForConfigLoaded() { }) } -export function getResolvedThemeConfig() { +export function getThemeConfig() { return loader!.resolvedConfig } diff --git a/theme/src/node/plugins/getPlugins.ts b/theme/src/node/plugins/getPlugins.ts index cb2cc0b3..0721f7e5 100644 --- a/theme/src/node/plugins/getPlugins.ts +++ b/theme/src/node/plugins/getPlugins.ts @@ -22,6 +22,7 @@ import { resolveSearchOptions, } from '../config/index.js' import { customContainerPlugins } from './containerPlugins.js' +import { markdownTitlePlugin } from './markdown-title.js' export interface SetupPluginOptions { app: App @@ -39,7 +40,7 @@ export function getPlugins({ const isProd = !app.env.isDev const plugins: PluginConfig = [ - + markdownTitlePlugin(), fontsPlugin(), contentUpdatePlugin(), activeHeaderLinksPlugin({ diff --git a/theme/src/node/prepare/index.ts b/theme/src/node/prepare/index.ts index 00a39ca7..6f4f27b7 100644 --- a/theme/src/node/prepare/index.ts +++ b/theme/src/node/prepare/index.ts @@ -1,6 +1,6 @@ import type { App } from 'vuepress' import { watch } from 'chokidar' -import { getResolvedThemeConfig } from '../loadConfig/index.js' +import { getThemeConfig } from '../loadConfig/index.js' import { prepareArticleTagColors } from './prepareArticleTagColor.js' import { preparedBlogData } from './prepareBlogData.js' import { prepareEncrypt } from './prepareEncrypt.js' @@ -10,7 +10,7 @@ import { prepareIcons } from './prepareIcons.js' export async function prepareData( app: App, ): Promise { - const { localeOptions, encrypt } = getResolvedThemeConfig() + const { localeOptions, encrypt } = getThemeConfig() await Promise.all([ prepareArticleTagColors(app), preparedBlogData(app, localeOptions, encrypt), diff --git a/theme/src/node/theme.ts b/theme/src/node/theme.ts index 5d5d1927..2dba7e69 100644 --- a/theme/src/node/theme.ts +++ b/theme/src/node/theme.ts @@ -4,38 +4,14 @@ import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js' import { getPlugins } from './plugins/index.js' import { extendsPageData, setupPage } from './setupPages.js' import { THEME_NAME, resolve, templates } from './utils/index.js' -import { - extendsBundlerOptions, - resolveAlias, - resolvePageHead, - resolveProvideData, - resolveThemeOptions, - templateBuildRenderer, -} from './config/index.js' -import { - getResolvedThemeConfig, - initConfigLoader, - onConfigChange, - waitForConfigLoaded, - watchConfigFile, -} from './loadConfig/index.js' -import { - generateAutoFrontmatter, - initAutoFrontmatter, - waitForAutoFrontmatter, - watchAutoFrontmatter, -} from './autoFrontmatter/index.js' +import { extendsBundlerOptions, resolveAlias, resolvePageHead, resolveProvideData, resolveThemeOptions, templateBuildRenderer } from './config/index.js' +import { getThemeConfig, initConfigLoader, waitForConfigLoaded, watchConfigFile } from './loadConfig/index.js' +import { generateAutoFrontmatter, initAutoFrontmatter, watchAutoFrontmatter } from './autoFrontmatter/index.js' import { prepareData, watchPrepare } from './prepare/index.js' import { prepareThemeData } from './prepare/prepareThemeData.js' export function plumeTheme(options: PlumeThemeOptions = {}): Theme { - const { - localeOptions, - pluginOptions, - hostname, - configFile, - cache, - } = resolveThemeOptions(options) + const { localeOptions, pluginOptions, hostname, configFile, cache } = resolveThemeOptions(options) return (app) => { initConfigLoader(app, localeOptions, { @@ -48,14 +24,6 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme { }, }) - waitForConfigLoaded().then(async ({ autoFrontmatter }) => { - autoFrontmatter ??= pluginOptions.frontmatter - if (autoFrontmatter !== false) { - await sleep(100) - generateAutoFrontmatter(app) - } - }) - return { name: THEME_NAME, @@ -69,42 +37,49 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme { plugins: getPlugins({ app, pluginOptions, hostname, cache }), + extendsBundlerOptions, + + templateBuildRenderer, + + extendsMarkdown: async (_, app) => { + const { autoFrontmatter } = await waitForConfigLoaded() + if ((autoFrontmatter ?? pluginOptions.frontmatter) !== false) { + await generateAutoFrontmatter(app) + // wait for autoFrontmatter generated + // i/o performance + await sleep(100) + } + }, + + extendsPage: async (page) => { + const { localeOptions } = getThemeConfig() + extendsPageData(page as Page, localeOptions) + resolvePageHead(page, localeOptions) + }, + onInitialized: async (app) => { - const { localeOptions } = await waitForConfigLoaded() + const { localeOptions } = getThemeConfig() await setupPage(app, localeOptions) }, onPrepared: async (app) => { - onConfigChange(async ({ localeOptions }) => { - await prepareThemeData(app, localeOptions) - await prepareData(app) - }) - const { localeOptions } = await waitForConfigLoaded() + const { localeOptions } = getThemeConfig() await prepareThemeData(app, localeOptions) await prepareData(app) }, onWatched: (app, watchers) => { - watchConfigFile(app, watchers) - watchPrepare(app, watchers) + watchConfigFile(app, watchers, async ({ localeOptions }) => { + await prepareThemeData(app, localeOptions) + await prepareData(app) + }) watchAutoFrontmatter(app, watchers, () => { - const autoFrontmatter = getResolvedThemeConfig().autoFrontmatter ?? pluginOptions.frontmatter + const autoFrontmatter = getThemeConfig().autoFrontmatter + ?? pluginOptions.frontmatter return autoFrontmatter !== false }) + watchPrepare(app, watchers) }, - - extendsPage: async (page) => { - const { localeOptions, autoFrontmatter } = await waitForConfigLoaded() - if ((autoFrontmatter ?? pluginOptions.frontmatter) !== false) { - await waitForAutoFrontmatter() - } - extendsPageData(page as Page, localeOptions) - resolvePageHead(page, localeOptions) - }, - - extendsBundlerOptions, - - templateBuildRenderer, } } }