@sugarat/theme 0.1.39 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/node.d.ts +32 -8
- package/node.js +313 -205
- package/package.json +5 -4
- package/src/components/BlogArticleAnalyze.vue +1 -1
- package/src/components/BlogFriendLink.vue +2 -2
- package/src/components/BlogHomeOverview.vue +1 -1
- package/src/components/BlogHotArticle.vue +1 -1
- package/src/components/BlogItem.vue +1 -1
- package/src/components/BlogRecommendArticle.vue +2 -2
- package/src/components/BlogSearch.vue +1 -1
- package/src/components/UserWorks.vue +1 -1
- package/src/composables/config/index.ts +24 -2
- package/src/node.ts +35 -366
- package/src/styles/index.scss +1 -1
- package/src/utils/{index.ts → client/index.ts} +1 -1
- package/src/utils/node/genFeed.ts +75 -0
- package/src/utils/node/index.ts +118 -0
- package/src/utils/node/mdPlugins.ts +95 -0
- package/src/utils/node/theme.ts +147 -0
- package/src/utils/node/vitePlugins.ts +98 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* eslint-disable global-require */
|
|
2
|
+
/* eslint-disable prefer-rest-params */
|
|
3
|
+
import { spawn, spawnSync } from 'child_process'
|
|
4
|
+
import { formatDate } from '../client'
|
|
5
|
+
|
|
6
|
+
export function clearMatterContent(content: string) {
|
|
7
|
+
let first___: unknown
|
|
8
|
+
let second___: unknown
|
|
9
|
+
|
|
10
|
+
const lines = content.split('\n').reduce<string[]>((pre, line) => {
|
|
11
|
+
// 移除开头的空白行
|
|
12
|
+
if (!line.trim() && pre.length === 0) {
|
|
13
|
+
return pre
|
|
14
|
+
}
|
|
15
|
+
if (line.trim() === '---') {
|
|
16
|
+
if (first___ === undefined) {
|
|
17
|
+
first___ = pre.length
|
|
18
|
+
} else if (second___ === undefined) {
|
|
19
|
+
second___ = pre.length
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
pre.push(line)
|
|
23
|
+
return pre
|
|
24
|
+
}, [])
|
|
25
|
+
return (
|
|
26
|
+
lines
|
|
27
|
+
// 剔除---之间的内容
|
|
28
|
+
.slice((second___ as number) || 0)
|
|
29
|
+
.join('\n')
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
export function getDefaultTitle(content: string) {
|
|
33
|
+
const title =
|
|
34
|
+
clearMatterContent(content)
|
|
35
|
+
.split('\n')
|
|
36
|
+
?.find((str) => {
|
|
37
|
+
return str.startsWith('# ')
|
|
38
|
+
})
|
|
39
|
+
?.slice(2)
|
|
40
|
+
.replace(/^\s+|\s+$/g, '') || ''
|
|
41
|
+
return title
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getFileBirthTime(url: string) {
|
|
45
|
+
let date = new Date()
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
// 参考 vitepress 中的 getGitTimestamp 实现
|
|
49
|
+
const infoStr = spawnSync('git', ['log', '-1', '--pretty="%ci"', url])
|
|
50
|
+
.stdout?.toString()
|
|
51
|
+
.replace(/["']/g, '')
|
|
52
|
+
.trim()
|
|
53
|
+
if (infoStr) {
|
|
54
|
+
date = new Date(infoStr)
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return formatDate(date)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return formatDate(date)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getGitTimestamp(file: string) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const child = spawn('git', ['log', '-1', '--pretty="%ci"', file])
|
|
66
|
+
let output = ''
|
|
67
|
+
child.stdout.on('data', (d) => {
|
|
68
|
+
output += String(d)
|
|
69
|
+
})
|
|
70
|
+
child.on('close', () => {
|
|
71
|
+
resolve(+new Date(output))
|
|
72
|
+
})
|
|
73
|
+
child.on('error', reject)
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getTextSummary(text: string, count = 100) {
|
|
78
|
+
return (
|
|
79
|
+
clearMatterContent(text)
|
|
80
|
+
.match(/^# ([\s\S]+)/m)?.[1]
|
|
81
|
+
// 除去标题
|
|
82
|
+
?.replace(/#/g, '')
|
|
83
|
+
// 除去图片
|
|
84
|
+
?.replace(/!\[.*?\]\(.*?\)/g, '')
|
|
85
|
+
// 除去链接
|
|
86
|
+
?.replace(/\[(.*?)\]\(.*?\)/g, '$1')
|
|
87
|
+
// 除去加粗
|
|
88
|
+
?.replace(/\*\*(.*?)\*\*/g, '$1')
|
|
89
|
+
?.split('\n')
|
|
90
|
+
?.filter((v) => !!v)
|
|
91
|
+
?.slice(1)
|
|
92
|
+
?.join('\n')
|
|
93
|
+
?.replace(/>(.*)/, '')
|
|
94
|
+
?.slice(0, count)
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function aliasObjectToArray(obj: Record<string, string>) {
|
|
99
|
+
return Object.entries(obj).map(([find, replacement]) => ({
|
|
100
|
+
find,
|
|
101
|
+
replacement
|
|
102
|
+
}))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const EXTERNAL_URL_RE = /^[a-z]+:/i
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Join two paths by resolving the slash collision.
|
|
109
|
+
*/
|
|
110
|
+
export function joinPath(base: string, path: string): string {
|
|
111
|
+
return `${base}${path}`.replace(/\/+/g, '/')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function withBase(base: string, path: string) {
|
|
115
|
+
return EXTERNAL_URL_RE.test(path) || path.startsWith('.')
|
|
116
|
+
? path
|
|
117
|
+
: joinPath(base, path)
|
|
118
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* eslint-disable global-require */
|
|
2
|
+
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
|
|
3
|
+
import type { UserConfig } from 'vitepress'
|
|
4
|
+
import { aliasObjectToArray } from './index'
|
|
5
|
+
import type { Theme } from '../../composables/config/index'
|
|
6
|
+
|
|
7
|
+
export function getMarkdownPlugins(cfg?: Partial<Theme.BlogConfig>) {
|
|
8
|
+
const markdownPlugin: any[] = []
|
|
9
|
+
// tabs支持
|
|
10
|
+
if (cfg?.tabs) {
|
|
11
|
+
markdownPlugin.push(tabsMarkdownPlugin)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 添加mermaid markdown 插件
|
|
15
|
+
if (cfg) {
|
|
16
|
+
cfg.mermaid = cfg?.mermaid ?? true
|
|
17
|
+
if (cfg?.mermaid !== false) {
|
|
18
|
+
const { MermaidMarkdown } = require('vitepress-plugin-mermaid')
|
|
19
|
+
markdownPlugin.push(MermaidMarkdown)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return markdownPlugin
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function registerMdPlugins(vpCfg: any, plugins: any[]) {
|
|
26
|
+
if (plugins.length) {
|
|
27
|
+
vpCfg.markdown = {
|
|
28
|
+
config(...rest: any[]) {
|
|
29
|
+
plugins.forEach((plugin) => {
|
|
30
|
+
plugin?.(...rest)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 流程图支持,配置mermaid
|
|
39
|
+
*/
|
|
40
|
+
export function assignMermaid(config: any) {
|
|
41
|
+
if (!config?.mermaid) return
|
|
42
|
+
|
|
43
|
+
if (!config.vite) config.vite = {}
|
|
44
|
+
if (!config.vite.plugins) config.vite.plugins = []
|
|
45
|
+
const { MermaidPlugin } = require('vitepress-plugin-mermaid')
|
|
46
|
+
config.vite.plugins.push(MermaidPlugin(config.mermaid))
|
|
47
|
+
if (!config.vite.resolve) config.vite.resolve = {}
|
|
48
|
+
if (!config.vite.resolve.alias) config.vite.resolve.alias = {}
|
|
49
|
+
|
|
50
|
+
config.vite.resolve.alias = [
|
|
51
|
+
...aliasObjectToArray({
|
|
52
|
+
...config.vite.resolve.alias,
|
|
53
|
+
'cytoscape/dist/cytoscape.umd.js': 'cytoscape/dist/cytoscape.esm.js',
|
|
54
|
+
mermaid: 'mermaid/dist/mermaid.esm.mjs'
|
|
55
|
+
}),
|
|
56
|
+
{ find: /^dayjs\/(.*).js/, replacement: 'dayjs/esm/$1' }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function wrapperCfgWithMermaid(config: UserConfig<Theme.Config>): any {
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
const extendThemeConfig = (config.extends?.themeConfig?.blog ||
|
|
63
|
+
{}) as Theme.BlogConfig
|
|
64
|
+
|
|
65
|
+
// 开关支持Mermaid
|
|
66
|
+
const resultConfig =
|
|
67
|
+
extendThemeConfig.mermaid === false
|
|
68
|
+
? config
|
|
69
|
+
: {
|
|
70
|
+
...config,
|
|
71
|
+
mermaid:
|
|
72
|
+
extendThemeConfig.mermaid === true ? {} : extendThemeConfig.mermaid
|
|
73
|
+
}
|
|
74
|
+
assignMermaid(resultConfig)
|
|
75
|
+
return resultConfig
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function supportRunExtendsPlugin(config: UserConfig<Theme.Config>) {
|
|
79
|
+
// 处理markdown插件
|
|
80
|
+
if (!config.markdown) config.markdown = {}
|
|
81
|
+
// 支持运行继承的markdown插件
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
if (config.extends?.markdown?.config) {
|
|
84
|
+
const markdownExtendsConfigOriginal =
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
config.extends?.markdown?.config
|
|
87
|
+
const selfMarkdownConfig = config.markdown?.config
|
|
88
|
+
|
|
89
|
+
config.markdown.config = (...rest: any[]) => {
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
selfMarkdownConfig?.(...rest)
|
|
92
|
+
markdownExtendsConfigOriginal?.(...rest)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
2
|
+
import glob from 'fast-glob'
|
|
3
|
+
import matter from 'gray-matter'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import path from 'path'
|
|
6
|
+
import type { Theme } from '../../composables/config/index'
|
|
7
|
+
import { getDefaultTitle, getFileBirthTime, getTextSummary } from './index'
|
|
8
|
+
import { formatDate } from '../client'
|
|
9
|
+
|
|
10
|
+
export function patchDefaultThemeSideBar(cfg?: Partial<Theme.BlogConfig>) {
|
|
11
|
+
return cfg?.blog !== false && cfg?.recommend !== false
|
|
12
|
+
? {
|
|
13
|
+
sidebar: [
|
|
14
|
+
{
|
|
15
|
+
text: '',
|
|
16
|
+
items: []
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
: undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// hack:RSS用
|
|
24
|
+
export const pageMap = new Map<string, string>()
|
|
25
|
+
|
|
26
|
+
export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
27
|
+
const srcDir = cfg?.srcDir || process.argv.slice(2)?.[1] || '.'
|
|
28
|
+
const files = glob.sync(`${srcDir}/**/*.md`, { ignore: ['node_modules'] })
|
|
29
|
+
|
|
30
|
+
// 文章数据
|
|
31
|
+
const data = files
|
|
32
|
+
.map((v) => {
|
|
33
|
+
let route = v
|
|
34
|
+
// 处理文件后缀名
|
|
35
|
+
.replace('.md', '')
|
|
36
|
+
|
|
37
|
+
// 去除 srcDir 处理目录名
|
|
38
|
+
if (route.startsWith('./')) {
|
|
39
|
+
route = route.replace(
|
|
40
|
+
new RegExp(
|
|
41
|
+
`^\\.\\/${path
|
|
42
|
+
.join(srcDir, '/')
|
|
43
|
+
.replace(new RegExp(`\\${path.sep}`, 'g'), '/')}`
|
|
44
|
+
),
|
|
45
|
+
''
|
|
46
|
+
)
|
|
47
|
+
} else {
|
|
48
|
+
route = route.replace(
|
|
49
|
+
new RegExp(
|
|
50
|
+
`^${path
|
|
51
|
+
.join(srcDir, '/')
|
|
52
|
+
.replace(new RegExp(`\\${path.sep}`, 'g'), '/')}`
|
|
53
|
+
),
|
|
54
|
+
''
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
// hack:RSS使用
|
|
58
|
+
pageMap.set(`/${route}`, v)
|
|
59
|
+
|
|
60
|
+
const fileContent = fs.readFileSync(v, 'utf-8')
|
|
61
|
+
// TODO:摘要生成优化
|
|
62
|
+
const { data: frontmatter, excerpt } = matter(fileContent, {
|
|
63
|
+
excerpt: true
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const meta: Partial<Theme.PageMeta> = {
|
|
67
|
+
...frontmatter
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!meta.title) {
|
|
71
|
+
meta.title = getDefaultTitle(fileContent)
|
|
72
|
+
}
|
|
73
|
+
if (!meta.date) {
|
|
74
|
+
// getGitTimestamp(v).then((v) => {
|
|
75
|
+
// meta.date = formatDate(v)
|
|
76
|
+
// })
|
|
77
|
+
meta.date = getFileBirthTime(v)
|
|
78
|
+
} else {
|
|
79
|
+
const timeZone = cfg?.timeZone ?? 8
|
|
80
|
+
meta.date = formatDate(
|
|
81
|
+
new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 处理tags和categories,兼容历史文章
|
|
86
|
+
meta.categories =
|
|
87
|
+
typeof meta.categories === 'string'
|
|
88
|
+
? [meta.categories]
|
|
89
|
+
: meta.categories
|
|
90
|
+
meta.tags = typeof meta.tags === 'string' ? [meta.tags] : meta.tags
|
|
91
|
+
meta.tag = [meta.tag || []]
|
|
92
|
+
.flat()
|
|
93
|
+
.concat([
|
|
94
|
+
...new Set([...(meta.categories || []), ...(meta.tags || [])])
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
// 获取摘要信息
|
|
98
|
+
const wordCount = 100
|
|
99
|
+
meta.description =
|
|
100
|
+
meta.description || getTextSummary(fileContent, wordCount)
|
|
101
|
+
|
|
102
|
+
// 获取封面图
|
|
103
|
+
meta.cover =
|
|
104
|
+
meta.cover ??
|
|
105
|
+
(fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || '')
|
|
106
|
+
|
|
107
|
+
// 是否发布 默认发布
|
|
108
|
+
if (meta.publish === false) {
|
|
109
|
+
meta.hidden = true
|
|
110
|
+
meta.recommend = false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
route: `/${route}`,
|
|
115
|
+
meta
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
.filter((v) => v.meta.layout !== 'home')
|
|
119
|
+
return data as Theme.PageData[]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function patchVPConfig(vpConfig: any, cfg?: Partial<Theme.BlogConfig>) {
|
|
123
|
+
// TODO: 待确定场景
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function patchVPThemeConfig(
|
|
127
|
+
cfg?: Partial<Theme.BlogConfig>,
|
|
128
|
+
vpThemeConfig: any = {}
|
|
129
|
+
) {
|
|
130
|
+
// 添加 icon
|
|
131
|
+
const RSS = cfg?.RSS
|
|
132
|
+
if (RSS && RSS.showIcon !== false) {
|
|
133
|
+
vpThemeConfig.socialLinks = [
|
|
134
|
+
{
|
|
135
|
+
icon: {
|
|
136
|
+
svg: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><path d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48s48 21.49 48 48s-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634c-5.214-80.05-69.243-143.92-149.123-149.123c-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425c110.546 5.974 198.997 94.536 204.964 204.964c.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038c-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432c167.83 6.025 302.21 141.191 308.205 308.205c.232 6.449-4.978 11.787-11.432 11.787z" fill="currentColor"></path></svg>'
|
|
137
|
+
},
|
|
138
|
+
link: RSS.url
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 用于自定义sidebar卡片slot
|
|
144
|
+
vpThemeConfig.sidebar = patchDefaultThemeSideBar(cfg)?.sidebar
|
|
145
|
+
|
|
146
|
+
return vpThemeConfig
|
|
147
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { SiteConfig } from 'vitepress'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { execSync } from 'child_process'
|
|
4
|
+
import type { Theme } from '../../composables/config/index'
|
|
5
|
+
import { genFeed } from './genFeed'
|
|
6
|
+
|
|
7
|
+
export function getVitePlugins(cfg?: Partial<Theme.BlogConfig>) {
|
|
8
|
+
const plugins: any[] = []
|
|
9
|
+
|
|
10
|
+
// Build完后运行的一系列列方法
|
|
11
|
+
const buildEndFn: any[] = []
|
|
12
|
+
// 执行自定义的 buildEnd 钩子
|
|
13
|
+
plugins.push(inlineBuildEndPlugin(buildEndFn))
|
|
14
|
+
|
|
15
|
+
// 内置简化版的pagefind
|
|
16
|
+
if (
|
|
17
|
+
cfg?.search === 'pagefind' ||
|
|
18
|
+
(cfg?.search instanceof Object && cfg.search.mode === 'pagefind')
|
|
19
|
+
) {
|
|
20
|
+
plugins.push(inlinePagefindPlugin(buildEndFn))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
buildEndFn.push(genFeed)
|
|
24
|
+
return plugins
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function registerVitePlugins(vpCfg: any, plugins: any[]) {
|
|
28
|
+
vpCfg.vite = {
|
|
29
|
+
plugins
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function inlinePagefindPlugin(buildEndFn: any[]) {
|
|
34
|
+
buildEndFn.push(() => {
|
|
35
|
+
// 调用pagefind
|
|
36
|
+
const ignore: string[] = [
|
|
37
|
+
// 侧边栏内容
|
|
38
|
+
'div.aside',
|
|
39
|
+
// 标题锚点
|
|
40
|
+
'a.header-anchor'
|
|
41
|
+
]
|
|
42
|
+
const { log } = console
|
|
43
|
+
log()
|
|
44
|
+
log('=== pagefind: https://pagefind.app/ ===')
|
|
45
|
+
let command = `npx pagefind --source ${path.join(
|
|
46
|
+
process.argv.slice(2)?.[1] || '.',
|
|
47
|
+
'.vitepress/dist'
|
|
48
|
+
)}`
|
|
49
|
+
|
|
50
|
+
if (ignore.length) {
|
|
51
|
+
command += ` --exclude-selectors "${ignore.join(', ')}"`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
log(command)
|
|
55
|
+
log()
|
|
56
|
+
execSync(command, {
|
|
57
|
+
stdio: 'inherit'
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
return {
|
|
61
|
+
name: '@sugarar/theme-plugin-pagefind',
|
|
62
|
+
enforce: 'pre',
|
|
63
|
+
// 添加检索的内容标识
|
|
64
|
+
transform(code: string, id: string) {
|
|
65
|
+
if (id.endsWith('theme-default/Layout.vue')) {
|
|
66
|
+
return code.replace('<VPContent>', '<VPContent data-pagefind-body>')
|
|
67
|
+
}
|
|
68
|
+
return code
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function inlineBuildEndPlugin(buildEndFn: any[]) {
|
|
74
|
+
let rewrite = false
|
|
75
|
+
return {
|
|
76
|
+
name: '@sugarar/theme-plugin-build-end',
|
|
77
|
+
enforce: 'pre',
|
|
78
|
+
configResolved(config: any) {
|
|
79
|
+
// 避免重复定义
|
|
80
|
+
if (rewrite) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
const vitepressConfig: SiteConfig = config.vitepress
|
|
84
|
+
if (!vitepressConfig) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
rewrite = true
|
|
88
|
+
// 添加 自定义 vitepress build 的钩子
|
|
89
|
+
const selfBuildEnd = vitepressConfig.buildEnd
|
|
90
|
+
vitepressConfig.buildEnd = (siteCfg) => {
|
|
91
|
+
selfBuildEnd?.(siteCfg)
|
|
92
|
+
buildEndFn
|
|
93
|
+
.filter((fn) => typeof fn === 'function')
|
|
94
|
+
.forEach((fn) => fn(siteCfg))
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|