update logic to handle config reloads

pull/4321/head
Divyansh Singh 11 months ago
parent 3673efa7ca
commit 06aa88e5dd

@ -28,7 +28,7 @@ import type {
import type { Logger } from 'vite' import type { Logger } from 'vite'
import { containerPlugin, type ContainerOptions } from './plugins/containers' import { containerPlugin, type ContainerOptions } from './plugins/containers'
import { gitHubAlertsPlugin } from './plugins/githubAlerts' import { gitHubAlertsPlugin } from './plugins/githubAlerts'
import { highlight } from './plugins/highlight' import { highlight as createHighlighter } from './plugins/highlight'
import { highlightLinePlugin } from './plugins/highlightLines' import { highlightLinePlugin } from './plugins/highlightLines'
import { imagePlugin, type Options as ImageOptions } from './plugins/image' import { imagePlugin, type Options as ImageOptions } from './plugins/image'
import { lineNumberPlugin } from './plugins/lineNumbers' import { lineNumberPlugin } from './plugins/lineNumbers'
@ -192,39 +192,35 @@ export interface MarkdownOptions extends Options {
export type MarkdownRenderer = MarkdownIt export type MarkdownRenderer = MarkdownIt
/** let md: MarkdownRenderer | undefined
* Keep a reference to the highlighter to avoid re-creating. let _disposeHighlighter: (() => void) | undefined
*
* This highlighter is used in the `createContentLoader` function so every time export function disposeMdItInstance() {
* this function is called, the highlighter will be re-created. At the end, if (md) {
* Shiki will slow down the build process because it must be a singleton. md = undefined
*/ _disposeHighlighter?.()
let highlighter: }
| ((str: string, lang: string, attrs: string) => string) }
| null
| undefined
export const createMarkdownRenderer = async ( export async function createMarkdownRenderer(
srcDir: string, srcDir: string,
options: MarkdownOptions = {}, options: MarkdownOptions = {},
base = '/', base = '/',
logger: Pick<Logger, 'warn'> = console logger: Pick<Logger, 'warn'> = console
): Promise<MarkdownRenderer> => { ): Promise<MarkdownRenderer> {
if (md) return md
const theme = options.theme ?? { light: 'github-light', dark: 'github-dark' } const theme = options.theme ?? { light: 'github-light', dark: 'github-dark' }
const codeCopyButtonTitle = options.codeCopyButtonTitle || 'Copy Code' const codeCopyButtonTitle = options.codeCopyButtonTitle || 'Copy Code'
const hasSingleTheme = typeof theme === 'string' || 'name' in theme const hasSingleTheme = typeof theme === 'string' || 'name' in theme
highlighter = let [highlight, dispose] = options.highlight
highlighter || ? [options.highlight, () => {}]
options.highlight || : await createHighlighter(theme, options, logger)
(await highlight(theme, options, logger))
const md = MarkdownIt({ _disposeHighlighter = dispose
html: true,
linkify: true, md = MarkdownIt({ html: true, linkify: true, highlight, ...options })
highlight: highlighter,
...options
})
md.linkify.set({ fuzzyLink: false }) md.linkify.set({ fuzzyLink: false })
md.use(restoreEntities) md.use(restoreEntities)

@ -23,7 +23,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
* 2. convert line numbers into line options: * 2. convert line numbers into line options:
* [{ line: number, classes: string[] }] * [{ line: number, classes: string[] }]
*/ */
const attrsToLines = (attrs: string): TransformerCompactLineOption[] => { function attrsToLines(attrs: string): TransformerCompactLineOption[] {
attrs = attrs.replace(/^(?:\[.*?\])?.*?([\d,-]+).*/, '$1').trim() attrs = attrs.replace(/^(?:\[.*?\])?.*?([\d,-]+).*/, '$1').trim()
const result: number[] = [] const result: number[] = []
if (!attrs) { if (!attrs) {
@ -51,7 +51,7 @@ export async function highlight(
theme: ThemeOptions, theme: ThemeOptions,
options: MarkdownOptions, options: MarkdownOptions,
logger: Pick<Logger, 'warn'> = console logger: Pick<Logger, 'warn'> = console
): Promise<(str: string, lang: string, attrs: string) => string> { ): Promise<[(str: string, lang: string, attrs: string) => string, () => void]> {
const { const {
defaultHighlightLang: defaultLang = '', defaultHighlightLang: defaultLang = '',
codeTransformers: userTransformers = [] codeTransformers: userTransformers = []
@ -95,7 +95,8 @@ export async function highlight(
const lineNoRE = /:(no-)?line-numbers(=\d*)?$/ const lineNoRE = /:(no-)?line-numbers(=\d*)?$/
const mustacheRE = /\{\{.*?\}\}/g const mustacheRE = /\{\{.*?\}\}/g
return (str: string, lang: string, attrs: string) => { return [
(str: string, lang: string, attrs: string) => {
const vPre = vueRE.test(lang) ? '' : 'v-pre' const vPre = vueRE.test(lang) ? '' : 'v-pre'
lang = lang =
lang lang
@ -105,7 +106,7 @@ export async function highlight(
.toLowerCase() || defaultLang .toLowerCase() || defaultLang
if (lang) { if (lang) {
const langLoaded = highlighter.getLoadedLanguages().includes(lang as any) const langLoaded = highlighter.getLoadedLanguages().includes(lang)
if (!langLoaded && !isSpecialLang(lang)) { if (!langLoaded && !isSpecialLang(lang)) {
logger.warn( logger.warn(
c.yellow( c.yellow(
@ -183,5 +184,7 @@ export async function highlight(
}) })
return restoreMustache(highlighted) return restoreMustache(highlighted)
} },
highlighter.dispose
]
} }

@ -16,6 +16,7 @@ import {
resolveAliases resolveAliases
} from './alias' } from './alias'
import { resolvePages, resolveUserConfig, type SiteConfig } from './config' import { resolvePages, resolveUserConfig, type SiteConfig } from './config'
import { disposeMdItInstance } from './markdown/markdown'
import { import {
clearCache, clearCache,
createMarkdownToVueRenderFn, createMarkdownToVueRenderFn,
@ -388,6 +389,7 @@ export async function createVitePressPlugin(
return return
} }
disposeMdItInstance()
clearCache() clearCache()
await recreateServer?.() await recreateServer?.()
return return

Loading…
Cancel
Save