perf(theme): improve node structure
This commit is contained in:
parent
5f743f13c3
commit
9e19de62bb
@ -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'
|
||||||
|
|||||||
18
theme/src/node/config/resolveAlias.ts
Normal file
18
theme/src/node/config/resolveAlias.ts
Normal 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),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
28
theme/src/node/config/resolveProvideData.ts
Normal file
28
theme/src/node/config/resolveProvideData.ts
Normal 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]),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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({
|
||||||
|
|||||||
19
theme/src/node/config/resolveThemeOption.ts
Normal file
19
theme/src/node/config/resolveThemeOption.ts
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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()
|
||||||
@ -5,4 +5,7 @@ export * from '../shared/index.js'
|
|||||||
|
|
||||||
export { plumeTheme }
|
export { plumeTheme }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 请使用 具名导出 替代 默认导出
|
||||||
|
*/
|
||||||
export default plumeTheme
|
export default plumeTheme
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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'
|
||||||
|
|
||||||
|
|||||||
@ -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: '简体中文',
|
||||||
|
|||||||
@ -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 }),
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
export interface PresetLocale {
|
|
||||||
home: string
|
|
||||||
blog: string
|
|
||||||
tag: string
|
|
||||||
archive: string
|
|
||||||
}
|
|
||||||
@ -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
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user