Skip to content

Commit 4c8d8da

Browse files
committed
fix: hack into vitepress to get naiveui ssr style working
1 parent fbad895 commit 4c8d8da

File tree

7 files changed

+60
-18
lines changed

7 files changed

+60
-18
lines changed

.prettierrc.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"printWidth": 100,
3+
"semi": false,
4+
"singleQuote": true
5+
}

.vitepress/config.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import { defineConfigWithTheme } from 'vitepress'
1+
import { EnhanceAppContext, defineConfigWithTheme } from 'vitepress'
2+
import { setup } from '@css-render/vue3-ssr'
23
import { createContainer } from './utils'
34
import { ThemeConfig } from './theme'
45
import tags from './tags'
6+
import { renderToString } from 'vue/server-renderer'
7+
import { Mutex } from 'async-mutex'
8+
9+
const transformHtmlMutex = new Mutex()
510

611
export default defineConfigWithTheme<ThemeConfig>({
712
title: 'SynBlog',
@@ -39,6 +44,29 @@ export default defineConfigWithTheme<ThemeConfig>({
3944

4045
ignoreDeadLinks: 'localhostLinks',
4146

47+
async transformHtml(html, id, ctx) {
48+
// VitePress 似乎是对所有页面同时进行渲染,但因为限制只能拿到一个固定的 App 实例,所以需要加互斥锁,防止抢 router
49+
const release = await transformHtmlMutex.acquire()
50+
try {
51+
// ./theme/index.ts 中存了一个全局的 App 实例下来
52+
const { app, router } = (globalThis as any).__EnhanceAppContext__ as EnhanceAppContext
53+
const { collect } = setup(app)
54+
55+
// 随后仿照 VitePress 走 SSR 渲染流程
56+
// https://github.com/vuejs/vitepress/blob/main/src/client/app/ssr.ts
57+
const path = (this.base || '/') + ctx.page.replace(/\.md$/, '.html')
58+
await router.go(path)
59+
await renderToString(app)
60+
61+
// 此时可以收集到所有的 CSS 了!
62+
const styles = collect()
63+
return html.replace('<head>', `<head>${styles}`)
64+
} finally {
65+
// 释放互斥锁
66+
release()
67+
}
68+
},
69+
4270
themeConfig: {
4371
tags,
4472

.vitepress/theme/Layout.vue

+3-15
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@
1111
<n-flex justify="space-between">
1212
<DateTag :time="currentPost.create" />
1313
<n-flex>
14-
<PostTag
15-
v-for="tag in currentPost.tags"
16-
:key="tag"
17-
:tag="tag"
18-
/>
14+
<PostTag v-for="tag in currentPost.tags" :key="tag" :tag="tag" />
1915
</n-flex>
2016
</n-flex>
2117
</template>
@@ -39,14 +35,7 @@ import { ref, computed, nextTick, watch, onMounted } from 'vue'
3935
import { useData } from 'vitepress'
4036
import DefaultTheme from 'vitepress/theme'
4137
import { data as posts } from '../posts.data'
42-
import {
43-
NConfigProvider,
44-
NThing,
45-
NDivider,
46-
NFlex,
47-
lightTheme,
48-
darkTheme,
49-
} from 'naive-ui'
38+
import { NConfigProvider, NThing, NDivider, NFlex, lightTheme, darkTheme } from 'naive-ui'
5039
import Giscus from '@giscus/vue'
5140
import mediumZoom from 'medium-zoom'
5241
import { ThemeConfig } from '.'
@@ -72,8 +61,7 @@ const mdImgSelector = '.vp-doc img'
7261
function setRandomTagline() {
7362
const taglineElement = document.querySelector('.tagline')
7463
if (!taglineElement) return
75-
taglineElement.innerHTML =
76-
taglines[Math.floor(Math.random() * taglines.length)]
64+
taglineElement.innerHTML = taglines[Math.floor(Math.random() * taglines.length)]
7765
}
7866
7967
function appendImgAlt() {

.vitepress/theme/custom.scss

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ $custom-blocks: (
1414
);
1515

1616
:root {
17-
--vp-font-family-mono: 'JetBrains Mono', ui-monospace, 'Menlo', 'Monaco',
18-
'Consolas', 'Liberation Mono', 'Courier New', monospace;
17+
--vp-font-family-mono: 'JetBrains Mono', ui-monospace, 'Menlo', 'Monaco', 'Consolas',
18+
'Liberation Mono', 'Courier New', monospace;
1919

2020
--vp-c-brand-1: #0d47a1;
2121
--vp-c-brand-2: #1565c0;

.vitepress/theme/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import './custom.scss'
77
const theme: Theme = {
88
extends: DefaultTheme,
99
Layout,
10+
async enhanceApp(ctx) {
11+
if (!(globalThis as any).__EnhanceAppContext__) {
12+
;(globalThis as any).__EnhanceAppContext__ = ctx
13+
}
14+
},
1015
}
1116

1217
export default theme

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@types/markdown-it-container": "^2.0.10",
1818
"@types/node": "^20.12.8",
1919
"@types/webfontloader": "^1.6.38",
20+
"async-mutex": "^0.5.0",
2021
"js-convert-case": "^4.2.0",
2122
"markdown-it-container": "^4.0.0",
2223
"medium-zoom": "^1.1.0",

pnpm-lock.yaml

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)