perf(theme): 优化 node 结构
This commit is contained in:
parent
e395e98128
commit
74a69948b8
@ -42,8 +42,9 @@ useEventListener('message', (event) => {
|
||||
&& payload
|
||||
&& payload.feature === props.feature
|
||||
&& payload.meta === props.meta
|
||||
)
|
||||
) {
|
||||
height.value = `${Math.ceil(payload.height)}px`
|
||||
}
|
||||
})
|
||||
|
||||
function parseData(data: string | MessageData): MessageData {
|
||||
|
||||
@ -34,8 +34,9 @@ export function useNetlifyFunctionsPlugin(app: App, options: UseNetlifyFunctionP
|
||||
(plugin: PluginObject) =>
|
||||
plugin.name === 'vuepress-plugin-netlify-functions',
|
||||
)
|
||||
)
|
||||
) {
|
||||
app.use(netlifyFunctionsPlugin())
|
||||
}
|
||||
|
||||
const { proxyPrefix, directory } = getOptions()
|
||||
const source = path.join(options.directory, '**/*.js')
|
||||
|
||||
@ -28,7 +28,7 @@ export function searchPlugin({
|
||||
|
||||
onPrepared: app => prepareSearchIndex({ app, isSearchable, searchOptions }),
|
||||
|
||||
onWatched: async (app, watchers) => {
|
||||
onWatched: (app, watchers) => {
|
||||
const searchIndexWatcher = chokidar.watch('pages/**/*.js', {
|
||||
cwd: app.dir.temp(),
|
||||
ignoreInitial: true,
|
||||
|
||||
@ -25,8 +25,9 @@ export function lineNumberPlugin(md: Markdown, { lineNumbers = true }: LineNumbe
|
||||
if (
|
||||
(!lineNumbers && !enableLineNumbers)
|
||||
|| (lineNumbers && disableLineNumbers)
|
||||
)
|
||||
) {
|
||||
return rawCode
|
||||
}
|
||||
|
||||
const code = rawCode.slice(
|
||||
rawCode.indexOf('<code>'),
|
||||
@ -39,8 +40,9 @@ export function lineNumberPlugin(md: Markdown, { lineNumbers = true }: LineNumbe
|
||||
typeof lineNumbers === 'number'
|
||||
&& lines.length < lineNumbers
|
||||
&& !enableLineNumbers
|
||||
)
|
||||
) {
|
||||
return rawCode
|
||||
}
|
||||
|
||||
const startNumbers
|
||||
= Number(info.match(LINE_NUMBERS_START_REGEXP)?.[1] ?? 1) - 1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { onMounted, onUnmounted, onUpdated } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
import type { PlumeThemeLocaleData } from '../../shared/index.js'
|
||||
import type { ThemeOutline } from '../../shared/index.js'
|
||||
import { throttleAndDebounce } from '../utils/index.js'
|
||||
import { useAside } from './aside.js'
|
||||
|
||||
@ -41,7 +41,7 @@ export type MenuItem = Omit<Header, 'slug' | 'children'> & {
|
||||
children?: MenuItem[]
|
||||
}
|
||||
|
||||
export function getHeaders(range: PlumeThemeLocaleData['outline']): MenuItem[] {
|
||||
export function getHeaders(range?: ThemeOutline): MenuItem[] {
|
||||
const headers = Array.from(
|
||||
document.querySelectorAll('.plume-content :where(h1,h2,h3,h4,h5,h6)'),
|
||||
)
|
||||
@ -68,8 +68,9 @@ function serializeHeader(h: Element): string {
|
||||
if (
|
||||
(node as Element).classList.contains('badge-view')
|
||||
|| (node as Element).classList.contains('ignore-header')
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
ret += node.textContent
|
||||
}
|
||||
@ -88,7 +89,7 @@ function serializeHeader(h: Element): string {
|
||||
return ret.trim()
|
||||
}
|
||||
|
||||
export function resolveHeaders(headers: MenuItem[], range?: PlumeThemeLocaleData['outline']): MenuItem[] {
|
||||
export function resolveHeaders(headers: MenuItem[], range?: ThemeOutline): MenuItem[] {
|
||||
if (range === false)
|
||||
return []
|
||||
|
||||
|
||||
18
theme/src/node/extendsBundlerOptions.ts
Normal file
18
theme/src/node/extendsBundlerOptions.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { addViteConfig, addViteOptimizeDepsInclude, addViteSsrNoExternal } from '@vuepress/helper'
|
||||
import type { App } from 'vuepress'
|
||||
|
||||
export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
|
||||
addViteConfig(bundlerOptions, app, {
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1024,
|
||||
},
|
||||
})
|
||||
|
||||
addViteOptimizeDepsInclude(bundlerOptions, app, '@vueuse/core', true)
|
||||
|
||||
addViteSsrNoExternal(bundlerOptions, app, [
|
||||
'@vuepress/helper',
|
||||
'@vuepress/plugin-reading-time',
|
||||
'@vuepress/plugin-watermark',
|
||||
])
|
||||
}
|
||||
@ -92,8 +92,9 @@ export function getPlugins({
|
||||
}))
|
||||
}
|
||||
|
||||
if (pluginOptions.nprogress !== false)
|
||||
if (pluginOptions.nprogress !== false) {
|
||||
plugins.push(nprogressPlugin())
|
||||
}
|
||||
|
||||
if (pluginOptions.git ?? isProd) {
|
||||
plugins.push(gitPlugin({
|
||||
@ -171,14 +172,17 @@ export function getPlugins({
|
||||
}))
|
||||
}
|
||||
|
||||
if (pluginOptions.comment)
|
||||
if (pluginOptions.comment) {
|
||||
plugins.push(commentPlugin(pluginOptions.comment))
|
||||
}
|
||||
|
||||
if (pluginOptions.baiduTongji !== false && pluginOptions.baiduTongji?.key && isProd)
|
||||
if (pluginOptions.baiduTongji !== false && pluginOptions.baiduTongji?.key && isProd) {
|
||||
plugins.push(baiduTongjiPlugin(pluginOptions.baiduTongji))
|
||||
}
|
||||
|
||||
if (pluginOptions.sitemap !== false && hostname && isProd)
|
||||
if (pluginOptions.sitemap !== false && hostname && isProd) {
|
||||
plugins.push(sitemapPlugin({ hostname }))
|
||||
}
|
||||
|
||||
if (pluginOptions.seo !== false && hostname && isProd) {
|
||||
plugins.push(seoPlugin({
|
||||
|
||||
11
theme/src/node/templateBuildRenderer.ts
Normal file
11
theme/src/node/templateBuildRenderer.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { type TemplateRendererContext, templateRenderer } from 'vuepress/utils'
|
||||
import { getThemePackage } from './utils.js'
|
||||
|
||||
export function templateBuildRenderer(template: string, context: TemplateRendererContext) {
|
||||
const pkg = getThemePackage()
|
||||
template = template
|
||||
.replace('{{ themeVersion }}', pkg.version || '')
|
||||
.replace(/^\s+|\s+$/gm, '')
|
||||
.replace(/\n/g, '')
|
||||
return templateRenderer(template, context)
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
import type { Page, Theme } from 'vuepress/core'
|
||||
import { templateRenderer } from 'vuepress/utils'
|
||||
import { addViteConfig, addViteOptimizeDepsInclude, addViteSsrNoExternal, isPlainObject } from '@vuepress/helper'
|
||||
import { isPlainObject } from '@vuepress/helper'
|
||||
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
|
||||
import { getPlugins } from './plugins/index.js'
|
||||
import { extendsPageData, setupPage } from './setupPages.js'
|
||||
import { THEME_NAME, getThemePackage, logger, resolve, templates } from './utils.js'
|
||||
import { THEME_NAME, logger, resolve, templates } from './utils.js'
|
||||
import { resolveEncrypt, resolveLocaleOptions, resolvePageHead } from './config/index.js'
|
||||
import { extendsBundlerOptions } from './extendsBundlerOptions.js'
|
||||
import { templateBuildRenderer } from './templateBuildRenderer.js'
|
||||
import { setupPrepare, watchPrepare } from './prepare/index.js'
|
||||
|
||||
export function plumeTheme({
|
||||
themePlugins,
|
||||
@ -15,7 +17,6 @@ export function plumeTheme({
|
||||
...localeOptions
|
||||
}: PlumeThemeOptions = {}): Theme {
|
||||
const pluginOptions = plugins ?? themePlugins ?? {}
|
||||
const pkg = getThemePackage()
|
||||
|
||||
const watermarkFullPage = isPlainObject(pluginOptions.watermark)
|
||||
? pluginOptions.watermark.fullPage !== false
|
||||
@ -29,6 +30,7 @@ export function plumeTheme({
|
||||
|
||||
return (app) => {
|
||||
localeOptions = resolveLocaleOptions(app, localeOptions)
|
||||
|
||||
return {
|
||||
name: THEME_NAME,
|
||||
|
||||
@ -43,34 +45,26 @@ export function plumeTheme({
|
||||
|
||||
plugins: getPlugins({ app, pluginOptions, localeOptions, encrypt, hostname }),
|
||||
|
||||
onInitialized: async app => await setupPage(app, localeOptions),
|
||||
onInitialized: async (app) => {
|
||||
await setupPage(app, localeOptions)
|
||||
},
|
||||
|
||||
onPrepared: async (app) => {
|
||||
await setupPrepare(app)
|
||||
},
|
||||
|
||||
onWatched: (app, watchers) => {
|
||||
watchPrepare(app, watchers)
|
||||
},
|
||||
|
||||
extendsPage: (page) => {
|
||||
extendsPageData(page as Page<PlumeThemePageData>, localeOptions)
|
||||
resolvePageHead(page, localeOptions)
|
||||
},
|
||||
|
||||
extendsBundlerOptions(bundlerOptions, app) {
|
||||
addViteConfig(bundlerOptions, app, {
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1024,
|
||||
},
|
||||
})
|
||||
addViteOptimizeDepsInclude(bundlerOptions, app, '@vueuse/core', true)
|
||||
addViteSsrNoExternal(bundlerOptions, app, [
|
||||
'@vuepress/helper',
|
||||
'@vuepress/plugin-reading-time',
|
||||
'@vuepress/plugin-watermark',
|
||||
])
|
||||
},
|
||||
extendsBundlerOptions,
|
||||
|
||||
templateBuildRenderer(template, context) {
|
||||
template = template
|
||||
.replace('{{ themeVersion }}', pkg.version || '')
|
||||
.replace(/^\s+|\s+$/gm, '')
|
||||
.replace(/\n/g, '')
|
||||
return templateRenderer(template, context)
|
||||
},
|
||||
templateBuildRenderer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
export type PlumeThemeImage =
|
||||
export type ThemeImage =
|
||||
| string
|
||||
| { src: string, alt?: string }
|
||||
| { dark: string, light: string, alt?: string }
|
||||
|
||||
export type ThemeColor = string | { light: string, dark: string }
|
||||
|
||||
export type ThemeOutline = false | number | [number, number] | 'deep'
|
||||
|
||||
export interface SocialLink {
|
||||
icon: SocialLinkIcon
|
||||
link: string
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { WatermarkPluginFrontmatter } from '@vuepress/plugin-watermark'
|
||||
import type { NavItemWithLink, PlumeThemeImage } from '.'
|
||||
import type { ThemeImage, ThemeOutline } from './base.js'
|
||||
import type { NavItemWithLink } from './options/navbar.js'
|
||||
|
||||
/* =============================== Home begin ==================================== */
|
||||
export interface PlumeThemeHomeFrontmatter extends Omit<PlumeThemeHomeBanner, 'type'> {
|
||||
@ -58,7 +59,7 @@ export interface PlumeThemeHomeHero extends PlumeHomeConfigBase {
|
||||
|
||||
export interface PlumeThemeHomeTextImage extends PlumeHomeConfigBase {
|
||||
type: 'text-image' | 'image-text'
|
||||
image: PlumeThemeImage
|
||||
image: ThemeImage
|
||||
width?: number | string
|
||||
title?: string
|
||||
description?: string
|
||||
@ -101,7 +102,7 @@ export interface PlumeThemeHomeProfile extends PlumeHomeConfigBase {
|
||||
type: 'profile'
|
||||
name?: string
|
||||
description?: string
|
||||
avatar?: PlumeThemeImage
|
||||
avatar?: ThemeImage
|
||||
circle?: boolean
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ export interface PlumeThemePageFrontmatter {
|
||||
contributors?: boolean
|
||||
prev?: string | NavItemWithLink
|
||||
next?: string | NavItemWithLink
|
||||
outline?: false | number | [number, number] | 'deep'
|
||||
outline?: ThemeOutline
|
||||
backToTop?: boolean
|
||||
externalLink?: boolean
|
||||
readingTime?: boolean
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { LocaleData } from 'vuepress/core'
|
||||
import type { NotesDataOptions } from '@vuepress-plume/plugin-notes-data'
|
||||
import type { SocialLink, SocialLinkIconUnion } from '../base.js'
|
||||
import type { SocialLink, SocialLinkIconUnion, ThemeOutline } from '../base.js'
|
||||
import type { PlumeThemeBlog } from '../blog.js'
|
||||
import type { NavItem } from './navbar.js'
|
||||
|
||||
@ -74,7 +74,7 @@ export interface PlumeThemeLocaleData extends LocaleData {
|
||||
*/
|
||||
notes?: false | NotesDataOptions
|
||||
|
||||
outline?: false | number | [number, number] | 'deep'
|
||||
outline?: ThemeOutline
|
||||
|
||||
/**
|
||||
* language text
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user