mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
refactor(theme): improve theme options (#463)
This commit is contained in:
parent
6442ffa25a
commit
b7ced3b501
@ -3,8 +3,6 @@ import type {
|
||||
AutoFrontmatterArray,
|
||||
AutoFrontmatterMarkdownFile,
|
||||
AutoFrontmatterObject,
|
||||
AutoFrontmatterOptions,
|
||||
PlumeThemeLocaleOptions,
|
||||
} from '../../shared/index.js'
|
||||
import { isArray, isEmptyObject, promiseParallel, toArray } from '@pengzhanbo/utils'
|
||||
import chokidar from 'chokidar'
|
||||
@ -34,10 +32,11 @@ export interface Generate {
|
||||
|
||||
let generate: Generate | null = null
|
||||
|
||||
export function initAutoFrontmatter(
|
||||
localeOptions: PlumeThemeLocaleOptions,
|
||||
autoFrontmatter: AutoFrontmatterOptions = {},
|
||||
) {
|
||||
export function initAutoFrontmatter() {
|
||||
const { localeOptions, autoFrontmatter = {} } = getThemeConfig()
|
||||
if (autoFrontmatter === false)
|
||||
return
|
||||
|
||||
const { include, exclude, frontmatter = {} } = resolveOptions(localeOptions, autoFrontmatter)
|
||||
|
||||
const globFilter = createFilter(include, exclude, { resolve: false })
|
||||
|
||||
@ -15,7 +15,11 @@ export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
|
||||
},
|
||||
})
|
||||
|
||||
addViteOptimizeDepsInclude(bundlerOptions, app, '@vueuse/core', true)
|
||||
addViteOptimizeDepsInclude(
|
||||
bundlerOptions,
|
||||
app,
|
||||
['@vueuse/core', 'bcrypt-ts/browser', '@vuepress/helper/client', '@iconify/vue', '@iconify/vue/offline'],
|
||||
)
|
||||
addViteOptimizeDepsExclude(bundlerOptions, app, '@theme')
|
||||
|
||||
addViteSsrNoExternal(bundlerOptions, app, [
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import type { TemplateRendererContext } from 'vuepress/utils'
|
||||
import type { PlumeThemeLocaleOptions } from '../../shared/index.js'
|
||||
import { templateRenderer } from 'vuepress/utils'
|
||||
import { getThemeConfig } from '../loadConfig/index.js'
|
||||
import { getThemePackage } from '../utils/index.js'
|
||||
|
||||
export function templateBuildRenderer(
|
||||
template: string,
|
||||
context: TemplateRendererContext,
|
||||
options: PlumeThemeLocaleOptions,
|
||||
) {
|
||||
const { localeOptions: options } = getThemeConfig()
|
||||
const pkg = getThemePackage()
|
||||
template = template
|
||||
.replace('{{ themeVersion }}', pkg.version || '')
|
||||
|
||||
@ -1,19 +1,30 @@
|
||||
import type { App, Page } from 'vuepress/core'
|
||||
import type { PlumeThemeLocaleOptions } from '../../shared/index.js'
|
||||
import { getRootLang } from '@vuepress/helper'
|
||||
import { createPage } from 'vuepress/core'
|
||||
import { getThemeConfig } from '../loadConfig/index.js'
|
||||
import { perfLog, perfMark, withBase } from '../utils/index.js'
|
||||
|
||||
export async function createPages(app: App, localeOption: PlumeThemeLocaleOptions) {
|
||||
if (localeOption.blog === false)
|
||||
function getRootLang(app: App): string {
|
||||
// infer from siteLocale
|
||||
const siteLocales = app.siteData.locales
|
||||
|
||||
if (siteLocales['/']?.lang)
|
||||
return siteLocales['/'].lang
|
||||
|
||||
return app.siteData.lang
|
||||
}
|
||||
|
||||
export async function createPages(app: App) {
|
||||
const { localeOptions } = getThemeConfig()
|
||||
|
||||
if (localeOptions.blog === false)
|
||||
return
|
||||
|
||||
perfMark('create:blog-pages')
|
||||
const pageList: Promise<Page>[] = []
|
||||
const locales = localeOption.locales || {}
|
||||
const locales = localeOptions.locales || {}
|
||||
const rootLang = getRootLang(app)
|
||||
|
||||
const blog = localeOption.blog || {}
|
||||
const blog = localeOptions.blog || {}
|
||||
const link = blog.link || '/blog/'
|
||||
|
||||
for (const localePath of Object.keys(locales)) {
|
||||
@ -24,7 +35,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.postList !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(link, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog', title: opt.blogText || localeOption.blogText || 'Blog' },
|
||||
frontmatter: { lang, _pageLayout: 'blog', title: opt.blogText || localeOptions.blogText || 'Blog' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -32,7 +43,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.tags !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.tagsLink || `${link}/tags/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-tags', title: opt.tagText || localeOption.tagText || 'Tags' },
|
||||
frontmatter: { lang, _pageLayout: 'blog-tags', title: opt.tagText || localeOptions.tagText || 'Tags' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -40,7 +51,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.archives !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.archivesLink || `${link}/archives/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-archives', title: opt.archiveText || localeOption.archiveText || 'Archives' },
|
||||
frontmatter: { lang, _pageLayout: 'blog-archives', title: opt.archiveText || localeOptions.archiveText || 'Archives' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -48,7 +59,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.categories !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.categoriesLink || `${link}/categories/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-categories', title: opt.categoryText || localeOption.categoryText || 'Categories' },
|
||||
frontmatter: { lang, _pageLayout: 'blog-categories', title: opt.categoryText || localeOptions.categoryText || 'Categories' },
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import type { Page } from 'vuepress/core'
|
||||
import type { PlumeThemeLocaleOptions, PlumeThemePageData } from '../../shared/index.js'
|
||||
import type { PlumeThemePageData } from '../../shared/index.js'
|
||||
import { getThemeConfig } from '../loadConfig/index.js'
|
||||
import { autoCategory } from './autoCategory.js'
|
||||
import { enableBulletin } from './pageBulletin.js'
|
||||
|
||||
export function extendsPageData(
|
||||
page: Page<PlumeThemePageData>,
|
||||
localeOptions: PlumeThemeLocaleOptions,
|
||||
) {
|
||||
const { localeOptions } = getThemeConfig()
|
||||
cleanPageData(page)
|
||||
autoCategory(page, localeOptions)
|
||||
enableBulletin(page, localeOptions)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { SeoPluginOptions } from '@vuepress/plugin-seo'
|
||||
import type { SitemapPluginOptions } from '@vuepress/plugin-sitemap'
|
||||
import type { App, PluginConfig } from 'vuepress/core'
|
||||
import type { PlumeThemeLocaleOptions, PlumeThemePluginOptions } from '../../shared/index.js'
|
||||
import type { PlumeThemePluginOptions } from '../../shared/index.js'
|
||||
import { contentUpdatePlugin } from '@vuepress-plume/plugin-content-update'
|
||||
import { fontsPlugin } from '@vuepress-plume/plugin-fonts'
|
||||
import { searchPlugin } from '@vuepress-plume/plugin-search'
|
||||
@ -23,6 +23,7 @@ import { sitemapPlugin } from '@vuepress/plugin-sitemap'
|
||||
import { watermarkPlugin } from '@vuepress/plugin-watermark'
|
||||
import { mdEnhancePlugin } from 'vuepress-plugin-md-enhance'
|
||||
import { markdownPowerPlugin } from 'vuepress-plugin-md-power'
|
||||
import { getThemeConfig } from '../loadConfig/index.js'
|
||||
|
||||
export interface SetupPluginOptions {
|
||||
app: App
|
||||
@ -31,16 +32,14 @@ export interface SetupPluginOptions {
|
||||
cache?: false | 'memory' | 'filesystem'
|
||||
}
|
||||
|
||||
export function getPlugins(
|
||||
options: PlumeThemeLocaleOptions,
|
||||
{
|
||||
app,
|
||||
pluginOptions,
|
||||
hostname,
|
||||
cache,
|
||||
}: SetupPluginOptions,
|
||||
): PluginConfig {
|
||||
export function getPlugins({
|
||||
app,
|
||||
pluginOptions,
|
||||
hostname,
|
||||
cache,
|
||||
}: SetupPluginOptions): PluginConfig {
|
||||
const isProd = app.env.isBuild
|
||||
const { localeOptions: options } = getThemeConfig()
|
||||
|
||||
const plugins: PluginConfig = [
|
||||
fontsPlugin(),
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import type { FSWatcher } from 'chokidar'
|
||||
import type { App } from 'vuepress'
|
||||
import type { PlumeThemeData, PlumeThemeLocaleOptions, PlumeThemePluginOptions } from '../../shared/index.js'
|
||||
import type { PlumeThemeData, PlumeThemePluginOptions } from '../../shared/index.js'
|
||||
import fs from 'node:fs/promises'
|
||||
import process from 'node:process'
|
||||
import { watch } from 'chokidar'
|
||||
import { resolveImageSize } from 'vuepress-plugin-md-power'
|
||||
import { hash } from 'vuepress/utils'
|
||||
import { resolveThemeData } from '../config/resolveThemeData.js'
|
||||
import { getThemeConfig } from '../loadConfig/index.js'
|
||||
import { perfLog, perfMark, resolveContent, writeTemp } from '../utils/index.js'
|
||||
|
||||
let bulletinFileWatcher: FSWatcher | null = null
|
||||
@ -16,10 +17,10 @@ process.on('exit', () => bulletinFileWatcher?.close())
|
||||
|
||||
export async function prepareThemeData(
|
||||
app: App,
|
||||
localeOptions: PlumeThemeLocaleOptions,
|
||||
pluginOptions: PlumeThemePluginOptions,
|
||||
): Promise<void> {
|
||||
perfMark('prepare:theme-data')
|
||||
const { localeOptions } = getThemeConfig()
|
||||
const resolvedThemeData = resolveThemeData(app, localeOptions)
|
||||
|
||||
await resolveProfileImage(app, resolvedThemeData, pluginOptions)
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
import type { Page, Theme } from 'vuepress/core'
|
||||
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
|
||||
import { sleep } from '@pengzhanbo/utils'
|
||||
import { generateAutoFrontmatter, initAutoFrontmatter, watchAutoFrontmatter } from './autoFrontmatter/index.js'
|
||||
import { extendsBundlerOptions, resolveAlias, 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 {
|
||||
extendsBundlerOptions,
|
||||
resolveAlias,
|
||||
resolveProvideData,
|
||||
resolveThemeOptions,
|
||||
templateBuildRenderer,
|
||||
} from './config/index.js'
|
||||
import { initConfigLoader, waitForConfigLoaded, watchConfigFile } from './loadConfig/index.js'
|
||||
import { createPages, extendsPageData } from './pages/index.js'
|
||||
import { getPlugins } from './plugins/index.js'
|
||||
import { prepareData, watchPrepare } from './prepare/index.js'
|
||||
@ -11,15 +21,18 @@ import { prepareThemeData } from './prepare/prepareThemeData.js'
|
||||
import { resolve, templates, THEME_NAME } from './utils/index.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, {
|
||||
configFile,
|
||||
onChange: ({ localeOptions, autoFrontmatter }) => {
|
||||
if (autoFrontmatter !== false)
|
||||
initAutoFrontmatter(localeOptions, autoFrontmatter)
|
||||
},
|
||||
onChange: initAutoFrontmatter,
|
||||
})
|
||||
|
||||
return {
|
||||
@ -33,17 +46,16 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
|
||||
|
||||
alias: resolveAlias(),
|
||||
|
||||
plugins: getPlugins(getThemeConfig().localeOptions, { app, pluginOptions, hostname, cache }),
|
||||
plugins: getPlugins({ app, pluginOptions, hostname, cache }),
|
||||
|
||||
extendsBundlerOptions,
|
||||
|
||||
templateBuildRenderer: (template, context) =>
|
||||
templateBuildRenderer(template, context, getThemeConfig().localeOptions),
|
||||
templateBuildRenderer,
|
||||
|
||||
extendsMarkdown: async (_, app) => {
|
||||
const { autoFrontmatter, localeOptions } = await waitForConfigLoaded()
|
||||
const { autoFrontmatter } = await waitForConfigLoaded()
|
||||
if (autoFrontmatter !== false) {
|
||||
initAutoFrontmatter(localeOptions, autoFrontmatter)
|
||||
initAutoFrontmatter()
|
||||
await generateAutoFrontmatter(app)
|
||||
// wait for autoFrontmatter generated
|
||||
// i/o performance
|
||||
@ -51,22 +63,22 @@ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
|
||||
}
|
||||
},
|
||||
|
||||
extendsPage: async (page) => {
|
||||
extendsPageData(page as Page<PlumeThemePageData>, getThemeConfig().localeOptions)
|
||||
extendsPage: (page) => {
|
||||
extendsPageData(page as Page<PlumeThemePageData>)
|
||||
},
|
||||
|
||||
onInitialized: async (app) => {
|
||||
await createPages(app, getThemeConfig().localeOptions)
|
||||
await createPages(app)
|
||||
},
|
||||
|
||||
onPrepared: async (app) => {
|
||||
await prepareThemeData(app, getThemeConfig().localeOptions, pluginOptions)
|
||||
await prepareThemeData(app, pluginOptions)
|
||||
await prepareData(app)
|
||||
},
|
||||
|
||||
onWatched: (app, watchers) => {
|
||||
watchConfigFile(app, watchers, async ({ localeOptions }) => {
|
||||
await prepareThemeData(app, localeOptions, pluginOptions)
|
||||
watchConfigFile(app, watchers, async () => {
|
||||
await prepareThemeData(app, pluginOptions)
|
||||
await prepareData(app)
|
||||
})
|
||||
watchAutoFrontmatter(app, watchers)
|
||||
|
||||
@ -16,5 +16,5 @@ export function getPackage() {
|
||||
}
|
||||
|
||||
export function getThemePackage() {
|
||||
return readJsonFileAsync(resolve('.../../package.json'))
|
||||
return readJsonFileAsync(resolve('../../package.json'))
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user