perf(theme): improve node structure

This commit is contained in:
pengzhanbo 2024-06-18 14:38:47 +08:00
parent 5f743f13c3
commit 9e19de62bb
15 changed files with 173 additions and 96 deletions

View File

@ -1,5 +1,12 @@
export * from './resolveThemeOption.js'
export * from './resolveLocaleOptions.js' export * from './resolveLocaleOptions.js'
export * from './resolveThemeData.js' export * from './resolveThemeData.js'
export * from './resolveProvideData.js'
export * from './resolveAlias.js'
export * from './extendsBundlerOptions.js'
export * from './templateBuildRenderer.js'
export * from './resolveSearchOptions.js' export * from './resolveSearchOptions.js'
export * from './resolvePageHead.js' export * from './resolvePageHead.js'
export * from './resolveEncrypt.js' export * from './resolveEncrypt.js'

View File

@ -0,0 +1,18 @@
import { fs, path } from 'vuepress/utils'
import { resolve } from '../utils.js'
export function resolveAlias() {
return {
...Object.fromEntries(
fs.readdirSync(
resolve('client/components'),
{ encoding: 'utf-8', recursive: true },
)
.filter(file => file.endsWith('.vue'))
.map(file => [
path.join('@theme', file),
resolve('client/components', file),
]),
),
}
}

View File

@ -0,0 +1,28 @@
import type { App } from 'vuepress'
import { entries, fromEntries, getRootLangPath, isPlainObject } from '@vuepress/helper'
import type { PlumeThemeEncrypt, PlumeThemePluginOptions } from '../../shared/index.js'
import { PRESET_LOCALES } from '../locales/index.js'
import { resolveEncrypt } from './resolveEncrypt.js'
export function resolveProvideData(
app: App,
plugins: PlumeThemePluginOptions,
encrypt?: PlumeThemeEncrypt,
): Record<string, any> {
const root = getRootLangPath(app)
return {
// 注入 加密配置
...resolveEncrypt(encrypt),
// 注入水印配置
__PLUME_WM_FP__: isPlainObject(plugins.watermark)
? plugins.watermark.fullPage !== false
: true,
// 注入多语言配置
__PLUME_PRESET_LOCALE__: fromEntries(
entries(PRESET_LOCALES)
.map(([locale, value]) => [locale === root ? '/' : locale, value]),
),
}
}

View File

@ -4,7 +4,10 @@ import type { DocsearchPluginOptions } from '@vuepress/plugin-docsearch'
import type { SearchPluginOptions } from '@vuepress-plume/plugin-search' import type { SearchPluginOptions } from '@vuepress-plume/plugin-search'
import { DOCSEARCH_LOCALES, SEARCH_LOCALES } from '../locales/index.js' import { DOCSEARCH_LOCALES, SEARCH_LOCALES } from '../locales/index.js'
export function resolveSearchOptions(app: App, { locales, ...options }: SearchPluginOptions = {}): SearchPluginOptions { export function resolveSearchOptions(
app: App,
{ locales, ...options }: SearchPluginOptions = {},
): SearchPluginOptions {
return { return {
...options, ...options,
locales: getLocaleConfig({ locales: getLocaleConfig({
@ -15,7 +18,10 @@ export function resolveSearchOptions(app: App, { locales, ...options }: SearchPl
} }
} }
export function resolveDocsearchOptions(app: App, { locales, ...options }: DocsearchPluginOptions = {}): DocsearchPluginOptions { export function resolveDocsearchOptions(
app: App,
{ locales, ...options }: DocsearchPluginOptions = {},
): DocsearchPluginOptions {
return { return {
...options, ...options,
locales: getLocaleConfig({ locales: getLocaleConfig({

View File

@ -0,0 +1,19 @@
import type { PlumeThemeOptions } from '../../shared/index.js'
import { logger } from '../utils.js'
export function resolveThemeOptions({ themePlugins, plugins, encrypt, hostname, ...localeOptions }: PlumeThemeOptions) {
const pluginOptions = plugins ?? themePlugins ?? {}
if (themePlugins) {
logger.warn(
`The 'themePlugins' option is deprecated. Please use 'plugins' instead.`,
)
}
return {
pluginOptions,
encrypt,
hostname,
localeOptions,
}
}

View File

@ -1,5 +1,5 @@
import { type TemplateRendererContext, templateRenderer } from 'vuepress/utils' import { type TemplateRendererContext, templateRenderer } from 'vuepress/utils'
import { getThemePackage } from './utils.js' import { getThemePackage } from '../utils.js'
export function templateBuildRenderer(template: string, context: TemplateRendererContext) { export function templateBuildRenderer(template: string, context: TemplateRendererContext) {
const pkg = getThemePackage() const pkg = getThemePackage()

View File

@ -5,4 +5,7 @@ export * from '../shared/index.js'
export { plumeTheme } export { plumeTheme }
/**
* @deprecated 使
*/
export default plumeTheme export default plumeTheme

View File

@ -1,6 +1,5 @@
import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search' import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search'
import type { PlumeThemeLocaleData } from '../../shared/index.js' import type { PlumeThemeLocaleData, PresetLocale } from '../../shared/index.js'
import type { PresetLocale } from '../types.js'
export const enLocale: PlumeThemeLocaleData = { export const enLocale: PlumeThemeLocaleData = {
selectLanguageName: 'English', selectLanguageName: 'English',

View File

@ -1,7 +1,6 @@
import type { DocsearchLocaleOptions } from '@vuepress/plugin-docsearch' import type { DocsearchLocaleOptions } from '@vuepress/plugin-docsearch'
import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search' import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search'
import type { PlumeThemeLocaleData } from '../../shared/index.js' import type { PlumeThemeLocaleData, PresetLocale } from '../../shared/index.js'
import type { PresetLocale } from '../types.js'
import { zhDocsearchLocale, zhLocale, zhPresetLocale, zhSearchLocale } from './zh.js' import { zhDocsearchLocale, zhLocale, zhPresetLocale, zhSearchLocale } from './zh.js'
import { enLocale, enPresetLocale, enSearchLocale } from './en.js' import { enLocale, enPresetLocale, enSearchLocale } from './en.js'

View File

@ -1,7 +1,6 @@
import type { DocsearchLocaleOptions } from '@vuepress/plugin-docsearch' import type { DocsearchLocaleOptions } from '@vuepress/plugin-docsearch'
import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search' import type { SearchLocaleOptions } from '@vuepress-plume/plugin-search'
import type { PlumeThemeLocaleData } from '../../shared/index.js' import type { PlumeThemeLocaleData, PresetLocale } from '../../shared/index.js'
import type { PresetLocale } from '../types.js'
export const zhLocale: PlumeThemeLocaleData = { export const zhLocale: PlumeThemeLocaleData = {
selectLanguageName: '简体中文', selectLanguageName: '简体中文',

View File

@ -1,62 +1,40 @@
import type { Page, Theme } from 'vuepress/core' import type { Page, Theme } from 'vuepress/core'
import { fs, path } from 'vuepress/utils'
import { isPlainObject } from '@vuepress/helper'
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js' import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
import { getPlugins } from './plugins/index.js' import { getPlugins } from './plugins/index.js'
import { extendsPageData, setupPage } from './setupPages.js' import { extendsPageData, setupPage } from './setupPages.js'
import { THEME_NAME, logger, resolve, templates } from './utils.js' import { THEME_NAME, resolve, templates } from './utils.js'
import { resolveEncrypt, resolveLocaleOptions, resolvePageHead } from './config/index.js' import {
import { extendsBundlerOptions } from './extendsBundlerOptions.js' extendsBundlerOptions,
import { templateBuildRenderer } from './templateBuildRenderer.js' resolveAlias,
resolveLocaleOptions,
resolvePageHead,
resolveProvideData,
resolveThemeOptions,
templateBuildRenderer,
} from './config/index.js'
import { setupPrepare, watchPrepare } from './prepare/index.js' import { setupPrepare, watchPrepare } from './prepare/index.js'
export function plumeTheme({ export function plumeTheme(options: PlumeThemeOptions = {}): Theme {
themePlugins, const {
plugins, localeOptions: rawLocaleOptions,
encrypt, pluginOptions,
hostname, hostname,
...localeOptions encrypt,
}: PlumeThemeOptions = {}): Theme { } = resolveThemeOptions(options)
const pluginOptions = plugins ?? themePlugins ?? {}
const watermarkFullPage = isPlainObject(pluginOptions.watermark)
? pluginOptions.watermark.fullPage !== false
: true
if (themePlugins) {
logger.warn(
`The 'themePlugins' option is deprecated. Please use 'plugins' instead.`,
)
}
return (app) => { return (app) => {
localeOptions = resolveLocaleOptions(app, localeOptions) const localeOptions = resolveLocaleOptions(app, rawLocaleOptions)
return { return {
name: THEME_NAME, name: THEME_NAME,
define: { define: resolveProvideData(app, pluginOptions, encrypt),
...resolveEncrypt(encrypt),
__PLUME_WM_FP__: watermarkFullPage,
},
templateBuild: templates('build.html'), templateBuild: templates('build.html'),
clientConfigFile: resolve('client/config.js'), clientConfigFile: resolve('client/config.js'),
alias: { alias: resolveAlias(),
...Object.fromEntries(
fs.readdirSync(
resolve('client/components'),
{ encoding: 'utf-8', recursive: true },
)
.filter(file => file.endsWith('.vue'))
.map(file => [
path.join('@theme', file),
resolve('client/components', file),
]),
),
},
plugins: getPlugins({ app, pluginOptions, localeOptions, encrypt, hostname }), plugins: getPlugins({ app, pluginOptions, localeOptions, encrypt, hostname }),

View File

@ -1,6 +0,0 @@
export interface PresetLocale {
home: string
blog: string
tag: string
archive: string
}

View File

@ -38,3 +38,10 @@ export type SocialLinkIconUnion =
| 'xbox' | 'xbox'
export type SocialLinkIcon = SocialLinkIconUnion | { svg: string } export type SocialLinkIcon = SocialLinkIconUnion | { svg: string }
export interface PresetLocale {
home: string
blog: string
tag: string
archive: string
}

View File

@ -48,9 +48,9 @@ export interface PlumeThemeLocaleData extends LocaleData {
social?: SocialLink[] social?: SocialLink[]
/** /**
* Navbar config *
* *
* Set to `false` to disable navbar in current locale * `false`
*/ */
navbar?: false | NavItem[] navbar?: false | NavItem[]
@ -75,114 +75,119 @@ export interface PlumeThemeLocaleData extends LocaleData {
/** /**
* *
* *
* notes配置到navbar中 * notes配置到navbar中
*/ */
notes?: false | NotesDataOptions notes?: false | NotesDataOptions
/**
*
*
*
*
*
*
* 'deep' [2, 6] <h2> <h6>
*
* @default [2, 3]
*/
outline?: ThemeOutline outline?: ThemeOutline
/** /**
* *
* *
* - `false`
* - `true`
* - `'left` sidebar
*
* @default true * @default true
*/ */
aside?: boolean | 'left' aside?: boolean | 'left'
/** /**
* language text *
*/ */
selectLanguageText?: string selectLanguageText?: string
/** /**
* language aria label * `aria-label`
*/ */
selectLanguageAriaLabel?: string selectLanguageAriaLabel?: string
/** /**
* language name *
*
* locales locale
*/ */
selectLanguageName?: string selectLanguageName?: string
/** /**
* Page meta - edit link config
* *
* Whether to show "Edit this page" or not *
* "编辑此页"
*/ */
editLink?: boolean editLink?: boolean
/** /**
* Page meta - edit link config * "编辑此页"
* *
* The text to replace the default "Edit this page" * @default "Edit this page"
*/ */
editLinkText?: string editLinkText?: string
/** /**
* Page meta - edit link config * "编辑此页"
*
* Pattern of edit link
* *
* @example ':repo/edit/:branch/:path' * @example ':repo/edit/:branch/:path'
*/ */
editLinkPattern?: string editLinkPattern?: string
/** /**
* Page meta - edit link config * , Edit this page
*
* Use `repo` config by default
*
* Set this config if your docs is placed in a different repo
*/ */
docsRepo?: string docsRepo?: string
/** /**
* Page meta - edit link config * `Edit this page`
*
* Set this config if the branch of your docs is not 'main'
*/ */
docsBranch?: string docsBranch?: string
/** /**
* Page meta - edit link config * `Edit this page`
*
* Set this config if your docs is placed in sub dir of your `docsRepo`
*/ */
docsDir?: string docsDir?: string
/** /**
* Page meta - last updated config *
* *
* Whether to show "Last Updated" or not * @default { text: 'Last Updated', formatOptions: { dateStyle: 'short', timeStyle: 'short' } }
*/ */
lastUpdated?: false | LastUpdatedOptions lastUpdated?: false | LastUpdatedOptions
/** /**
* @deprecated Use `lastUpdated.text` instead. * @deprecated 使 `lastUpdated.text` .
* *
* Set custom last updated text. * "最后更新时间"
* *
* @default 'Last updated' * @default 'Last updated'
*/ */
lastUpdatedText?: string lastUpdatedText?: string
/** /**
* Page meta - contributors config *
*
* Whether to show "Contributors" or not
*/ */
contributors?: boolean contributors?: boolean
/** /**
* Page meta - contributors config *
*
* The text to replace the default "Contributors"
*/ */
contributorsText?: string contributorsText?: string
// backToHome?: string
/** /**
* sidebar menu label *
*
* @default 'Menu'
*/ */
sidebarMenuLabel?: string sidebarMenuLabel?: string
/** /**
* return to top label *
*
* @default 'return to top'
*/ */
returnToTopLabel?: string returnToTopLabel?: string
@ -193,15 +198,30 @@ export interface PlumeThemeLocaleData extends LocaleData {
*/ */
outlineLabel?: string outlineLabel?: string
/**
*
*
* @default 'Previous Page'
*/
prevPageLabel?: string prevPageLabel?: string
/**
*
*
* @default 'Next Page'
*/
nextPageLabel?: string nextPageLabel?: string
/** /**
* *
*
* @default true
*/ */
externalLinkIcon?: string externalLinkIcon?: string
/**
*
*/
footer?: footer?:
| false | false
| { | {
@ -210,7 +230,7 @@ export interface PlumeThemeLocaleData extends LocaleData {
} }
/** /**
* 404 page options * 404
*/ */
notFound?: { notFound?: {
code?: string | number code?: string | number