Skip to content

Commit 0c8cf0d

Browse files
authored
perf: extract social icons as plugin to avoid unused icons (#2768)
1 parent fc5092f commit 0c8cf0d

File tree

5 files changed

+52
-12
lines changed

5 files changed

+52
-12
lines changed

src/client/shim.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ declare module 'mark.js/src/vanilla.js' {
3333
const mark: Mark
3434
export default mark
3535
}
36+
37+
declare module 'virtual:vp-social-icons' {
38+
const data: Record<string, string>
39+
export default data
40+
}

src/client/theme-default/components/VPSocialLink.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts" setup>
22
import type { DefaultTheme } from 'vitepress/theme'
33
import { computed } from 'vue'
4-
import { icons } from '../support/socialIcons'
4+
import icons from 'virtual:vp-social-icons'
55
66
const props = defineProps<{
77
icon: DefaultTheme.SocialLinkIcon

src/node/plugin.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@ import {
1414
SITE_DATA_REQUEST_PATH,
1515
resolveAliases
1616
} from './alias'
17-
import { resolveUserConfig, resolvePages, type SiteConfig } from './config'
17+
import { resolvePages, resolveUserConfig, type SiteConfig } from './config'
1818
import {
1919
clearCache,
2020
createMarkdownToVueRenderFn,
2121
type MarkdownCompileResult
2222
} from './markdownToVue'
23-
import { slash, type PageDataPayload } from './shared'
24-
import { staticDataPlugin } from './plugins/staticDataPlugin'
25-
import { webFontsPlugin } from './plugins/webFontsPlugin'
2623
import { dynamicRoutesPlugin } from './plugins/dynamicRoutesPlugin'
27-
import { rewritesPlugin } from './plugins/rewritesPlugin'
2824
import { localSearchPlugin } from './plugins/localSearchPlugin'
29-
import { serializeFunctions, deserializeFunctions } from './utils/fnSerialize'
25+
import { rewritesPlugin } from './plugins/rewritesPlugin'
26+
import { socialIconsPlugin } from './plugins/socialIconsPlugin'
27+
import { staticDataPlugin } from './plugins/staticDataPlugin'
28+
import { webFontsPlugin } from './plugins/webFontsPlugin'
29+
import { slash, type PageDataPayload } from './shared'
30+
import { deserializeFunctions, serializeFunctions } from './utils/fnSerialize'
3031

3132
declare module 'vite' {
3233
interface UserConfig {
@@ -381,6 +382,7 @@ export async function createVitePressPlugin(
381382
...(userViteConfig?.plugins || []),
382383
await localSearchPlugin(siteConfig),
383384
staticDataPlugin,
384-
await dynamicRoutesPlugin(siteConfig)
385+
await dynamicRoutesPlugin(siteConfig),
386+
socialIconsPlugin(siteConfig)
385387
]
386388
}

src/client/theme-default/support/socialIcons.ts renamed to src/node/plugins/socialIconsPlugin.ts

+36-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
// Used under CC0 1.0 from https://simpleicons.org/
1+
import type { Plugin } from 'vite'
2+
import type { SiteConfig } from '../config'
3+
import type { DefaultTheme } from '../shared'
24

3-
export const icons = {
5+
// used under CC0 1.0 from https://simpleicons.org/
6+
const socialIcons = {
47
discord:
58
'<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Discord</title><path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg>',
69
facebook:
@@ -16,7 +19,36 @@ export const icons = {
1619
slack:
1720
'<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Slack</title><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"/></svg>',
1821
twitter:
19-
'<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>',
22+
'<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M21.543 7.104c.015.211.015.423.015.636 0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041 4.93 4.93 0 0 1-4.6-3.42 4.916 4.916 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.887 4.887 0 0 0 2.235.616A4.928 4.928 0 0 1 1.67 3.148 13.98 13.98 0 0 0 11.82 8.292a4.929 4.929 0 0 1 8.39-4.49 9.868 9.868 0 0 0 3.128-1.196 4.941 4.941 0 0 1-2.165 2.724A9.828 9.828 0 0 0 24 4.555a10.019 10.019 0 0 1-2.457 2.549z"/></svg>',
23+
x: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>X</title><path d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg>',
2024
youtube:
2125
'<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>'
22-
} as const
26+
}
27+
28+
const virtualModuleId = 'virtual:vp-social-icons'
29+
const resolvedVirtualModuleId = '\0' + virtualModuleId
30+
31+
export const socialIconsPlugin = (
32+
siteConfig: SiteConfig<DefaultTheme.Config>
33+
): Plugin => ({
34+
name: 'vitepress:social-icon',
35+
36+
resolveId(id) {
37+
if (id === virtualModuleId) {
38+
return resolvedVirtualModuleId
39+
}
40+
},
41+
42+
load(id) {
43+
if (id === resolvedVirtualModuleId) {
44+
const usedIcons: string[] | undefined =
45+
siteConfig.site.themeConfig.socialLinks?.map(({ icon }) =>
46+
typeof icon === 'string' ? icon : ''
47+
)
48+
const icons = Object.fromEntries(
49+
Object.entries(socialIcons).filter(([key]) => usedIcons?.includes(key))
50+
)
51+
return `export default ${JSON.stringify(icons)}`
52+
}
53+
}
54+
})

types/default-theme.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ export namespace DefaultTheme {
311311
| 'mastodon'
312312
| 'slack'
313313
| 'twitter'
314+
| 'x'
314315
| 'youtube'
315316
| { svg: string }
316317

0 commit comments

Comments
 (0)