diff --git a/plugins/plugin-md-power/src/client/components/CanIUse.vue b/plugins/plugin-md-power/src/client/components/CanIUse.vue index c23310fc..ba4e841e 100644 --- a/plugins/plugin-md-power/src/client/components/CanIUse.vue +++ b/plugins/plugin-md-power/src/client/components/CanIUse.vue @@ -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 { diff --git a/plugins/plugin-netlify-functions/src/node/useNetlifyFunctionsPlugins.ts b/plugins/plugin-netlify-functions/src/node/useNetlifyFunctionsPlugins.ts index a896e321..6d573764 100644 --- a/plugins/plugin-netlify-functions/src/node/useNetlifyFunctionsPlugins.ts +++ b/plugins/plugin-netlify-functions/src/node/useNetlifyFunctionsPlugins.ts @@ -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') diff --git a/plugins/plugin-search/src/node/searchPlugin.ts b/plugins/plugin-search/src/node/searchPlugin.ts index c9ac70c9..22b068ae 100644 --- a/plugins/plugin-search/src/node/searchPlugin.ts +++ b/plugins/plugin-search/src/node/searchPlugin.ts @@ -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, diff --git a/plugins/plugin-shikiji/src/node/markdown/lineNumberPlugin.ts b/plugins/plugin-shikiji/src/node/markdown/lineNumberPlugin.ts index fe911347..59aa7960 100644 --- a/plugins/plugin-shikiji/src/node/markdown/lineNumberPlugin.ts +++ b/plugins/plugin-shikiji/src/node/markdown/lineNumberPlugin.ts @@ -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(''), @@ -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 diff --git a/theme/src/client/composables/outline.ts b/theme/src/client/composables/outline.ts index be0506cf..d8e6672f 100644 --- a/theme/src/client/composables/outline.ts +++ b/theme/src/client/composables/outline.ts @@ -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 & { 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 [] diff --git a/theme/src/node/extendsBundlerOptions.ts b/theme/src/node/extendsBundlerOptions.ts new file mode 100644 index 00000000..a19d59dd --- /dev/null +++ b/theme/src/node/extendsBundlerOptions.ts @@ -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', + ]) +} diff --git a/theme/src/node/plugins/getPlugins.ts b/theme/src/node/plugins/getPlugins.ts index 0c25a8de..29350018 100644 --- a/theme/src/node/plugins/getPlugins.ts +++ b/theme/src/node/plugins/getPlugins.ts @@ -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({ diff --git a/theme/src/node/templateBuildRenderer.ts b/theme/src/node/templateBuildRenderer.ts new file mode 100644 index 00000000..fed950ae --- /dev/null +++ b/theme/src/node/templateBuildRenderer.ts @@ -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) +} diff --git a/theme/src/node/theme.ts b/theme/src/node/theme.ts index d8791887..1d6a24d9 100644 --- a/theme/src/node/theme.ts +++ b/theme/src/node/theme.ts @@ -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, 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, } } } diff --git a/theme/src/shared/base.ts b/theme/src/shared/base.ts index 14703167..3a361c8e 100644 --- a/theme/src/shared/base.ts +++ b/theme/src/shared/base.ts @@ -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 diff --git a/theme/src/shared/frontmatter.ts b/theme/src/shared/frontmatter.ts index e784e7e4..22e40098 100644 --- a/theme/src/shared/frontmatter.ts +++ b/theme/src/shared/frontmatter.ts @@ -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 { @@ -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 diff --git a/theme/src/shared/options/locale.ts b/theme/src/shared/options/locale.ts index edeb5663..06f8810e 100644 --- a/theme/src/shared/options/locale.ts +++ b/theme/src/shared/options/locale.ts @@ -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