Merge branch 'main' into feat/loading-lazy

pull/3346/head
Divyansh Singh 2 years ago committed by GitHub
commit 0fe161fa65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,22 @@
# [1.0.0-rc.33](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.32...v1.0.0-rc.33) (2023-12-26)
### Features
- allow explicitly mark code element as `.vp-copy-ignore` ([#3360](https://github.com/vuejs/vitepress/issues/3360)) ([93122ee](https://github.com/vuejs/vitepress/commit/93122eee20cb6586026c1ffac04d9787861cc2f3))
- **build:** enable VUE_PROD_HYDRATION_MISMATCH_DETAILS when DEBUG is truthy ([f4d4280](https://github.com/vuejs/vitepress/commit/f4d4280d7d1728a966bb04968a9bac10470c3d06)), closes [#422](https://github.com/vuejs/vitepress/issues/422)
### Performance Improvements
- implement concurrent promise pooling for render task ([#3366](https://github.com/vuejs/vitepress/issues/3366))
# [1.0.0-rc.32](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.31...v1.0.0-rc.32) (2023-12-16)
### Features
- allow ignoring node in header ([#3331](https://github.com/vuejs/vitepress/issues/3331)) ([e4bf1e4](https://github.com/vuejs/vitepress/commit/e4bf1e48e6a1592d583b218425c1fa7497955dc5))
- expose `shikijiSetup` hook ([#3344](https://github.com/vuejs/vitepress/issues/3344)) ([d12e23d](https://github.com/vuejs/vitepress/commit/d12e23ddf69480418078ff39846c99ecf2e1eb1b))
- update shikiji, support twoslash ([#3339](https://github.com/vuejs/vitepress/issues/3339)) ([8800195](https://github.com/vuejs/vitepress/commit/880019545795fd075be89d94794bfbd05af461b5))
# [1.0.0-rc.31](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.30...v1.0.0-rc.31) (2023-11-25)
### Bug Fixes

@ -1,43 +0,0 @@
<script setup>
import icon from './documate.vue'
</script>
<template>
<div class="ad-component">
<a target="_blank" href="https://github.com/aircodelabs/documate">
<icon class="icon"/>
<span>Embed AI chat in your VitePress using your own content. Open-source.</span>
<span class="cta">Try now </span>
</a>
</div>
</template>
<style scoped>
.ad-component {
margin-bottom: 2rem;
padding: .5rem .85rem;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
text-decoration: none;
color: var(--vp-c-text-2);
transition: color 0.4s ease-in-out;
font-size: 0.8rem;
}
.ad-component:hover {
color: var(--vp-c-text-1);
}
.ad-component .icon {
display: inline-block;
width: .75rem;
height: .75rem;
margin-right: 0.3rem;
}
.ad-component .cta {
margin-left: 0.3rem;
text-decoration: underline;
text-underline-offset: 2px;
}
</style>

@ -1,5 +0,0 @@
<template>
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.79938 23.5375C3.57959 23.516 3.36074 23.4856 3.14338 23.4465C2.98375 23.4179 2.83446 23.3477 2.71056 23.243C2.58666 23.1384 2.49252 23.0029 2.43762 22.8503C2.38272 22.6977 2.36899 22.5334 2.39782 22.3738C2.42665 22.2142 2.49702 22.065 2.60185 21.9412C3.10678 21.346 3.45159 20.6318 3.60369 19.8662C3.632 19.7246 3.57661 19.476 3.29108 19.1978C1.26031 17.2225 0 14.5431 0 11.5769C0 5.38615 5.44985 0.5 12 0.5C18.5502 0.5 24 5.38615 24 11.5769C24 17.7677 18.5502 22.6538 12 22.6538C10.9748 22.6538 9.97785 22.5345 9.02523 22.3105C7.46812 23.289 5.62931 23.7208 3.79938 23.5375ZM12.7957 18.2748C12.7504 18.3232 12.6907 18.3474 12.6165 18.3474C12.5423 18.3474 12.4805 18.3232 12.431 18.2748C12.3857 18.2305 12.3569 18.1721 12.3445 18.0995C12.258 17.4628 12.1632 16.9288 12.0602 16.4976C11.9571 16.0664 11.8212 15.7158 11.6522 15.4457C11.4832 15.1717 11.2587 14.9541 10.9784 14.7929C10.7023 14.6317 10.3459 14.5028 9.90907 14.4061C9.47225 14.3053 8.93448 14.2146 8.29574 14.134C8.21745 14.1259 8.15357 14.0977 8.10412 14.0494C8.05468 14.001 8.02995 13.9406 8.02995 13.868C8.02995 13.7955 8.05468 13.7351 8.10412 13.6867C8.15357 13.6383 8.21745 13.6101 8.29574 13.602C8.9386 13.5335 9.47844 13.4549 9.91525 13.3663C10.3521 13.2736 10.7106 13.1447 10.9908 12.9794C11.271 12.8142 11.4956 12.5925 11.6646 12.3145C11.8376 12.0364 11.9736 11.6798 12.0725 11.2445C12.1756 10.8093 12.2662 10.2713 12.3445 9.63052C12.3569 9.56201 12.3857 9.50559 12.431 9.46126C12.4805 9.4129 12.5423 9.38872 12.6165 9.38872C12.6907 9.38872 12.7504 9.4129 12.7957 9.46126C12.8452 9.50559 12.8761 9.56201 12.8885 9.63052C12.9709 10.2713 13.0615 10.8093 13.1604 11.2445C13.2635 11.6798 13.3994 12.0364 13.5684 12.3145C13.7374 12.5925 13.962 12.8142 14.2422 12.9794C14.5224 13.1447 14.8809 13.2736 15.3178 13.3663C15.7586 13.4549 16.2985 13.5335 16.9372 13.602C17.0155 13.6101 17.0773 13.6383 17.1226 13.6867C17.1721 13.7351 17.1968 13.7955 17.1968 13.868C17.1968 13.9406 17.1721 14.001 17.1226 14.0494C17.0773 14.0977 17.0155 14.1259 16.9372 14.134C16.2985 14.2025 15.7586 14.2831 15.3178 14.3758C14.8809 14.4645 14.5224 14.5914 14.2422 14.7567C13.962 14.9219 13.7374 15.1435 13.5684 15.4216C13.3994 15.6997 13.2635 16.0563 13.1604 16.4915C13.0615 16.9268 12.9709 17.4628 12.8885 18.0995C12.8761 18.1721 12.8452 18.2305 12.7957 18.2748ZM8.77789 11.9578C8.74492 11.9901 8.70371 12.0062 8.65425 12.0062C8.54711 12.0062 8.4853 11.9498 8.46882 11.8369C8.42349 11.4541 8.37404 11.1559 8.32047 10.9423C8.2669 10.7247 8.18448 10.5614 8.07322 10.4526C7.96195 10.3438 7.79094 10.2612 7.56017 10.2048C7.33351 10.1484 7.02239 10.0859 6.62679 10.0174C6.50316 10.0013 6.44135 9.94284 6.44135 9.84209C6.44135 9.74538 6.49492 9.68694 6.60206 9.66679C7.00591 9.59425 7.32115 9.52977 7.5478 9.47335C7.77857 9.4129 7.95164 9.33029 8.06703 9.2255C8.18242 9.1167 8.2669 8.95549 8.32047 8.74191C8.37404 8.52832 8.42349 8.23212 8.46882 7.8533C8.4853 7.74046 8.54711 7.68404 8.65425 7.68404C8.7614 7.68404 8.82116 7.73845 8.83352 7.84725C8.88708 8.23413 8.94066 8.53839 8.99423 8.76004C9.0478 8.97766 9.13022 9.14289 9.24149 9.25573C9.35686 9.36454 9.52788 9.44716 9.75454 9.50358C9.9853 9.55596 10.3026 9.61037 10.7065 9.66679C10.7518 9.67485 10.7889 9.695 10.8177 9.72724C10.8507 9.75545 10.8672 9.79373 10.8672 9.84209C10.8672 9.94284 10.8136 10.0013 10.7065 10.0174C10.3026 10.094 9.98736 10.1625 9.76072 10.2229C9.53406 10.2834 9.36305 10.368 9.24767 10.4768C9.13228 10.5816 9.0478 10.7408 8.99423 10.9544C8.94066 11.1639 8.88708 11.4601 8.83352 11.843C8.82939 11.8873 8.81085 11.9256 8.77789 11.9578ZM11.6213 7.98024C11.6048 8.05278 11.5636 8.08905 11.4977 8.08905C11.4235 8.08905 11.3823 8.05278 11.374 7.98024C11.3163 7.67799 11.2628 7.45635 11.2133 7.3153C11.168 7.17022 11.0712 7.06746 10.9228 7.007C10.7786 6.94655 10.5354 6.88812 10.1934 6.8317C10.1192 6.81558 10.0821 6.77528 10.0821 6.7108C10.0821 6.63826 10.1192 6.59796 10.1934 6.5899C10.5354 6.52945 10.7786 6.47102 10.9228 6.4146C11.0712 6.35415 11.168 6.2534 11.2133 6.11235C11.2628 5.96727 11.3163 5.74159 11.374 5.43531C11.3823 5.36277 11.4235 5.3265 11.4977 5.3265C11.5636 5.3265 11.6048 5.36277 11.6213 5.43531C11.6749 5.74159 11.7264 5.96727 11.7758 6.11235C11.8253 6.2534 11.9221 6.35415 12.0663 6.4146C12.2106 6.47102 12.4537 6.52945 12.7957 6.5899C12.8699 6.59796 12.907 6.63826 12.907 6.7108C12.907 6.77528 12.8699 6.81558 12.7957 6.8317C12.4537 6.88812 12.2106 6.94655 12.0663 7.007C11.9221 7.06746 11.8253 7.17022 11.7758 7.3153C11.7264 7.45635 11.6749 7.67799 11.6213 7.98024Z" />
</svg>
</template>

@ -1,13 +0,0 @@
// .vitepress/theme/index.js
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import AdComponent from './AdComponent.vue'
export default {
...DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'doc-before': () => h(AdComponent)
})
}
}

@ -108,7 +108,7 @@ For more details, see [Frontmatter](../reference/frontmatter-config).
:tada: :100:
A [list of all emojis](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.json) is available.
A [list of all emojis](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs) is available.
## Table of Contents

@ -406,6 +406,20 @@ export interface DocFooter {
Can be used to customize the dark mode switch label. This label is only displayed in the mobile view.
## lightModeSwitchTitle
- Type: `string`
- Default: `Switch to light theme`
Can be used to customize the light mode switch title that appears on hovering.
## darkModeSwitchTitle
- Type: `string`
- Default: `Switch to dark theme`
Can be used to customize the dark mode switch title that appears on hovering.
## sidebarMenuLabel
- Type: `string`

@ -212,6 +212,9 @@ interface TeamMember {
// URL for the sponsor page for the member.
sponsor?: string
// Text for the sponsor link. Defaults to 'Sponsor'.
actionText?: string
}
```

@ -24,6 +24,62 @@ export default {
}
```
:::details Dynamic (Async) Config
If you need to dynamically generate the config, you can also default export a function. For example:
```ts
import { defineConfig } from 'vitepress'
export default async () => defineConfig({
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
return {
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
// theme level config options
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
}
})
```
You can also use top-level `await`. For example:
```ts
import { defineConfig } from 'vitepress'
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
export default defineConfig({
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
// theme level config options
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
})
```
:::
### Config Intellisense
Using the `defineConfig` helper will provide TypeScript-powered intellisense for config options. Assuming your IDE supports it, this should work in both JavaScript and TypeScript.

@ -1,9 +1,9 @@
{
"name": "vitepress",
"version": "1.0.0-rc.31",
"version": "1.0.0-rc.33",
"description": "Vite & Vue powered static site generator",
"type": "module",
"packageManager": "pnpm@8.11.0",
"packageManager": "pnpm@8.12.1",
"main": "dist/node/index.js",
"types": "types/index.d.ts",
"exports": {
@ -93,22 +93,22 @@
"@docsearch/css": "^3.5.2",
"@docsearch/js": "^3.5.2",
"@types/markdown-it": "^13.0.7",
"@vitejs/plugin-vue": "^4.5.0",
"@vitejs/plugin-vue": "^5.0.0",
"@vue/devtools-api": "^6.5.1",
"@vueuse/core": "^10.6.1",
"@vueuse/integrations": "^10.6.1",
"@vueuse/core": "^10.7.0",
"@vueuse/integrations": "^10.7.0",
"focus-trap": "^7.5.4",
"mark.js": "8.11.1",
"minisearch": "^6.3.0",
"mrmime": "^1.0.1",
"shikiji": "^0.9.2",
"shikiji-transformers": "^0.9.2",
"vite": "^5.0.2",
"vue": "^3.3.8"
"mrmime": "^2.0.0",
"shikiji": "^0.9.12",
"shikiji-transformers": "^0.9.12",
"vite": "^5.0.10",
"vue": "^3.4.0-rc.2"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4.3.2",
"postcss": "^8.4.31"
"postcss": "^8.4.32"
},
"peerDependenciesMeta": {
"markdown-it-mathjax3": {
@ -120,16 +120,16 @@
},
"devDependencies": {
"@clack/prompts": "^0.7.0",
"@mdit-vue/plugin-component": "^1.0.0",
"@mdit-vue/plugin-frontmatter": "^1.0.0",
"@mdit-vue/plugin-headers": "^1.0.0",
"@mdit-vue/plugin-sfc": "^1.0.0",
"@mdit-vue/plugin-title": "^1.0.0",
"@mdit-vue/plugin-toc": "^1.0.0",
"@mdit-vue/shared": "^1.0.0",
"@rollup/plugin-alias": "^5.0.1",
"@mdit-vue/plugin-component": "^2.0.0",
"@mdit-vue/plugin-frontmatter": "^2.0.0",
"@mdit-vue/plugin-headers": "^2.0.0",
"@mdit-vue/plugin-sfc": "^2.0.0",
"@mdit-vue/plugin-title": "^2.0.0",
"@mdit-vue/plugin-toc": "^2.0.0",
"@mdit-vue/shared": "^2.0.0",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@types/compression": "^1.7.5",
@ -144,57 +144,59 @@
"@types/markdown-it-emoji": "^2.0.4",
"@types/micromatch": "^4.0.6",
"@types/minimist": "^1.2.5",
"@types/node": "^20.10.0",
"@types/node": "^20.10.5",
"@types/postcss-prefix-selector": "^1.16.3",
"@types/prompts": "^2.4.9",
"@vue/shared": "^3.3.8",
"@vue/shared": "^3.3.13",
"chokidar": "^3.5.3",
"compression": "^1.7.4",
"conventional-changelog-cli": "^4.1.0",
"cross-spawn": "^7.0.3",
"debug": "^4.3.4",
"esbuild": "^0.19.7",
"esbuild": "^0.19.10",
"escape-html": "^1.0.3",
"execa": "^8.0.1",
"fast-glob": "^3.3.2",
"fs-extra": "^11.1.1",
"fs-extra": "^11.2.0",
"get-port": "^7.0.0",
"gray-matter": "^4.0.3",
"lint-staged": "^15.1.0",
"lint-staged": "^15.2.0",
"lodash.template": "^4.5.0",
"lru-cache": "^10.1.0",
"markdown-it": "^13.0.2",
"markdown-it": "^14.0.0",
"markdown-it-anchor": "^8.6.7",
"markdown-it-attrs": "^4.1.6",
"markdown-it-container": "^3.0.0",
"markdown-it-emoji": "^2.0.2",
"markdown-it-container": "^4.0.0",
"markdown-it-emoji": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
"micromatch": "^4.0.5",
"minimist": "^1.2.8",
"nanoid": "^5.0.3",
"nanoid": "^5.0.4",
"npm-run-all": "^4.1.5",
"ora": "^7.0.1",
"ora": "^8.0.1",
"p-map": "^7.0.0",
"path-to-regexp": "^6.2.1",
"picocolors": "^1.0.0",
"pkg-dir": "^8.0.0",
"playwright-chromium": "^1.40.0",
"playwright-chromium": "^1.40.1",
"polka": "1.0.0-next.23",
"postcss-prefix-selector": "^1.16.0",
"prettier": "^3.1.0",
"prettier": "^3.1.1",
"prompts": "^2.4.2",
"punycode": "^2.3.1",
"rimraf": "^5.0.5",
"rollup": "^4.5.2",
"rollup": "^4.9.1",
"rollup-plugin-dts": "^6.1.0",
"rollup-plugin-esbuild": "^6.1.0",
"semver": "^7.5.4",
"shikiji-core": "^0.9.12",
"simple-git-hooks": "^2.9.0",
"sirv": "^2.0.3",
"sirv": "^2.0.4",
"sitemap": "^7.1.1",
"supports-color": "^9.4.0",
"typescript": "^5.3.2",
"vitest": "^1.0.0-beta.4",
"vue-tsc": "^1.8.22",
"typescript": "^5.3.3",
"vitest": "^1.1.0",
"vue-tsc": "^1.8.26",
"wait-on": "^7.2.0"
},
"simple-git-hooks": {

File diff suppressed because it is too large Load Diff

@ -16,12 +16,15 @@ export function useCopyCode() {
parent.className
)
let text = ''
const ignoredNodes = ['.vp-copy-ignore', '.diff.remove']
sibling
.querySelectorAll('span.line:not(.diff.remove)')
.forEach((node) => (text += (node.textContent || '') + '\n'))
text = text.slice(0, -1)
// Clone the node and remove the ignored nodes
const clone = sibling.cloneNode(true) as HTMLElement
clone
.querySelectorAll(ignoredNodes.join(','))
.forEach((node) => node.remove())
let text = clone.textContent || ''
if (isShell) {
text = text.replace(/^ *(\$|>) /gm, '').trim()

@ -89,7 +89,7 @@ export function initData(route: Route): VitePressData {
frontmatter: computed(() => route.data.frontmatter),
params: computed(() => route.data.params),
lang: computed(() => site.value.lang),
dir: computed(() => site.value.dir),
dir: computed(() => route.data.frontmatter.dir || site.value.dir || 'ltr'),
localeIndex: computed(() => site.value.localeIndex || 'root'),
title: computed(() => {
return createTitle(site.value, route.data)

@ -42,7 +42,11 @@ async function update() {
}
function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
const options = Object.assign<{}, {}, DocSearchProps>({}, userOptions, {
const options = Object.assign<
{},
DefaultTheme.AlgoliaSearchOptions,
Partial<DocSearchProps>
>({}, userOptions, {
container: '#docsearch',
navigator: {
@ -69,7 +73,6 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
})
},
// @ts-expect-error vue-tsc thinks this should return Vue JSX but it returns the required React one
hitComponent({ hit, children }) {
return {
__v: null,
@ -80,7 +83,7 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
props: { href: hit.url, children }
}
}
})
}) as DocSearchProps
docsearch(options)
}

@ -4,7 +4,6 @@ import {
computedAsync,
debouncedWatch,
onKeyStroke,
reactify,
useEventListener,
useLocalStorage,
useScrollLock,
@ -23,7 +22,6 @@ import {
onMounted,
ref,
shallowRef,
toRef,
watch,
watchEffect,
type Ref
@ -32,7 +30,7 @@ import type { ModalTranslations } from '../../../../types/local-search'
import { pathToFile } from '../../app/utils'
import { useData } from '../composables/data'
import { LRUCache } from '../support/lru'
import { createTranslate } from '../support/translation'
import { createSearchTranslate } from '../support/translation'
const emit = defineEmits<{
(e: 'close'): void
@ -361,10 +359,7 @@ const defaultTranslations: { modal: ModalTranslations } = {
}
}
const $t = reactify(createTranslate)(
toRef(() => theme.value.search?.options),
defaultTranslations
)
const $t = createSearchTranslate(defaultTranslations)
// Back

@ -1,11 +1,6 @@
<script lang="ts" setup>
import { reactify } from '@vueuse/core'
import { toRef } from 'vue'
import type { ButtonTranslations } from '../../../../types/local-search'
import { useData } from '../composables/data'
import { createTranslate } from '../support/translation'
const { theme } = useData()
import { createSearchTranslate } from '../support/translation'
// Button-Translations
const defaultTranslations: { button: ButtonTranslations } = {
@ -15,10 +10,7 @@ const defaultTranslations: { button: ButtonTranslations } = {
}
}
const $t = reactify(createTranslate)(
toRef(() => theme.value.search?.options),
defaultTranslations
)
const $t = createSearchTranslate(defaultTranslations)
</script>
<template>

@ -5,14 +5,16 @@ import VPSwitch from './VPSwitch.vue'
import VPIconMoon from './icons/VPIconMoon.vue'
import VPIconSun from './icons/VPIconSun.vue'
const { isDark } = useData()
const { isDark, theme } = useData()
const toggleAppearance = inject('toggle-appearance', () => {
isDark.value = !isDark.value
})
const switchTitle = computed(() => {
return isDark.value ? 'Switch to light theme' : 'Switch to dark theme'
return isDark.value
? theme.value.lightModeSwitchTitle || 'Switch to light theme'
: theme.value.darkModeSwitchTitle || 'Switch to dark theme'
})
</script>

@ -47,7 +47,7 @@ withDefaults(defineProps<Props>(), {
</div>
<div v-if="member.sponsor" class="sp">
<VPLink class="sp-link" :href="member.sponsor" no-icon>
<VPIconHeart class="sp-icon" /> Sponsor
<VPIconHeart class="sp-icon" /> {{ member.actionText || 'Sponsor' }}
</VPLink>
</div>
</article>

@ -39,7 +39,6 @@ body {
font-weight: 400;
color: var(--vp-c-text-1);
background-color: var(--vp-c-bg);
direction: ltr;
font-synthesis: style;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;

@ -3,14 +3,14 @@ import { useData } from '../composables/data'
/**
* @param themeObject Can be an object with `translations` and `locales` properties
*/
export function createTranslate(
themeObject: any,
export function createSearchTranslate(
defaultTranslations: Record<string, any>
): (key: string) => string {
const { localeIndex } = useData()
const { localeIndex, theme } = useData()
function translate(key: string): string {
const keyPath = key.split('.')
const themeObject = theme.value.search?.options
const isObject = themeObject && typeof themeObject === 'object'
const locales =

@ -1,12 +1,14 @@
import { createHash } from 'crypto'
import fs from 'fs-extra'
import { createRequire } from 'module'
import pMap from 'p-map'
import path from 'path'
import { packageDirectorySync } from 'pkg-dir'
import { rimraf } from 'rimraf'
import { pathToFileURL } from 'url'
import type { BuildOptions, Rollup } from 'vite'
import { resolveConfig, type SiteConfig } from '../config'
import { clearCache } from '../markdownToVue'
import { slash, type HeadConfig } from '../shared'
import { deserializeFunctions, serializeFunctions } from '../utils/fnSerialize'
import { task } from '../utils/task'
@ -106,23 +108,23 @@ export async function build(
}
}
await Promise.all(
['404.md', ...siteConfig.pages]
.map((page) => siteConfig.rewrites.map[page] || page)
.map((page) =>
renderPage(
render,
siteConfig,
page,
clientResult,
appChunk,
cssChunk,
assets,
pageToHashMap,
metadataScript,
additionalHeadTags
)
await pMap(
['404.md', ...siteConfig.pages],
async (page) => {
await renderPage(
render,
siteConfig,
siteConfig.rewrites.map[page] || page,
clientResult,
appChunk,
cssChunk,
assets,
pageToHashMap,
metadataScript,
additionalHeadTags
)
},
{ concurrency: siteConfig.buildConcurrency }
)
})
@ -139,6 +141,7 @@ export async function build(
await generateSitemap(siteConfig)
await siteConfig.buildEnd?.(siteConfig)
clearCache()
siteConfig.logger.info(
`build complete in ${((Date.now() - start) / 1000).toFixed(2)}s.`

@ -104,7 +104,8 @@ export async function resolveConfig(
const { pages, dynamicRoutes, rewrites } = await resolvePages(
srcDir,
userConfig
userConfig,
logger
)
const config: SiteConfig = {
@ -141,7 +142,8 @@ export async function resolveConfig(
transformPageData: userConfig.transformPageData,
rewrites,
userConfig,
sitemap: userConfig.sitemap
sitemap: userConfig.sitemap,
buildConcurrency: userConfig.buildConcurrency ?? 64
}
// to be shared with content loaders

@ -17,7 +17,8 @@ import { slugify } from '@mdit-vue/shared'
import MarkdownIt from 'markdown-it'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import emojiPlugin from 'markdown-it-emoji'
// @ts-ignore
import { full as emojiPlugin } from 'markdown-it-emoji'
import type { Logger } from 'vite'
import { containerPlugin, type ContainerOptions } from './plugins/containers'
import { highlight } from './plugins/highlight'

@ -95,22 +95,6 @@ export async function createVitePressPlugin(
}
}
const getMergedAssetUrlOptions = () => {
const { transformAssetUrls } = userVuePluginOptions?.template ?? {}
const assetUrlOptions = { includeAbsolute: true }
if (transformAssetUrls && typeof transformAssetUrls === 'object') {
// presence of array fields means this is raw tags config
if (Object.values(transformAssetUrls).some((val) => Array.isArray(val))) {
return { ...assetUrlOptions, tags: transformAssetUrls as any }
} else {
return { ...assetUrlOptions, ...transformAssetUrls }
}
} else {
return assetUrlOptions
}
}
// lazy require plugin-vue to respect NODE_ENV in @vue/compiler-x
const vuePlugin = await import('@vitejs/plugin-vue').then((r) =>
r.default({
@ -121,8 +105,7 @@ export async function createVitePressPlugin(
compilerOptions: {
...userVuePluginOptions?.template?.compilerOptions,
isCustomElement
},
transformAssetUrls: getMergedAssetUrlOptions()
}
}
})
)
@ -169,7 +152,8 @@ export async function createVitePressPlugin(
site.themeConfig?.search?.provider === 'algolia' ||
!!site.themeConfig?.algolia, // legacy
__CARBON__: !!site.themeConfig?.carbonAds,
__ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir)
__ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir),
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: !!process.env.DEBUG
},
optimizeDeps: {
// force include vue to avoid duplicated copies when linked + optimized
@ -284,7 +268,11 @@ export async function createVitePressPlugin(
if (file.endsWith('.md')) {
Object.assign(
siteConfig,
await resolvePages(siteConfig.srcDir, siteConfig.userConfig)
await resolvePages(
siteConfig.srcDir,
siteConfig.userConfig,
siteConfig.logger
)
)
}

@ -1,6 +1,7 @@
import {
loadConfigFromFile,
normalizePath,
type Logger,
type Plugin,
type ViteDevServer
} from 'vite'
@ -13,7 +14,11 @@ import { resolveRewrites } from './rewritesPlugin'
export const dynamicRouteRE = /\[(\w+?)\]/g
export async function resolvePages(srcDir: string, userConfig: UserConfig) {
export async function resolvePages(
srcDir: string,
userConfig: UserConfig,
logger: Logger
) {
// Important: fast-glob doesn't guarantee order of the returned files.
// We must sort the pages so the input list to rollup is stable across
// builds - otherwise different input order could result in different exports
@ -39,7 +44,11 @@ export async function resolvePages(srcDir: string, userConfig: UserConfig) {
;(dynamicRouteRE.test(file) ? dynamicRouteFiles : pages).push(file)
})
const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
const dynamicRoutes = await resolveDynamicRoutes(
srcDir,
dynamicRouteFiles,
logger
)
pages.push(...dynamicRoutes.routes.map((r) => r.path))
const rewrites = resolveRewrites(pages, userConfig.rewrites)
@ -141,7 +150,7 @@ export const dynamicRoutesPlugin = async (
if (!/\.md$/.test(ctx.file)) {
Object.assign(
config,
await resolvePages(config.srcDir, config.userConfig)
await resolvePages(config.srcDir, config.userConfig, config.logger)
)
}
for (const id of mods) {
@ -154,7 +163,8 @@ export const dynamicRoutesPlugin = async (
export async function resolveDynamicRoutes(
srcDir: string,
routes: string[]
routes: string[],
logger: Logger
): Promise<SiteConfig['dynamicRoutes']> {
const pendingResolveRoutes: Promise<ResolvedRouteConfig[]>[] = []
const routeFileToModulesMap: Record<string, Set<string>> = {}
@ -170,7 +180,7 @@ export async function resolveDynamicRoutes(
const pathsFile = paths.find((p) => fs.existsSync(p))
if (pathsFile == null) {
console.warn(
logger.warn(
c.yellow(
`Missing paths file for dynamic route ${route}: ` +
`a corresponding ${paths[0]} (or .ts/.mjs/.mts) file is needed.`
@ -183,15 +193,15 @@ export async function resolveDynamicRoutes(
let mod = routeModuleCache.get(pathsFile)
if (!mod) {
try {
mod = (await loadConfigFromFile({} as any, pathsFile)) as RouteModule
mod = (await loadConfigFromFile(
{} as any,
pathsFile,
undefined,
'silent'
)) as RouteModule
routeModuleCache.set(pathsFile, mod)
} catch (e) {
console.warn(
c.yellow(
`Invalid paths file export in ${pathsFile}. ` +
`Expects default export of an object with a "paths" property.`
)
)
} catch (e: any) {
logger.warn(`${c.yellow(`Failed to load ${pathsFile}:`)}\n${e.stack}`)
continue
}
}
@ -210,7 +220,7 @@ export async function resolveDynamicRoutes(
const loader = mod!.config.paths
if (!loader) {
console.warn(
logger.warn(
c.yellow(
`Invalid paths file export in ${pathsFile}. ` +
`Missing "paths" property from default export.`

@ -147,6 +147,15 @@ export interface UserConfig<ThemeConfig = any>
*/
useWebFonts?: boolean
/**
* This option allows you to configure the concurrency of the build.
* A lower number will reduce the memory usage but will increase the build time.
*
* @experimental
* @default 64
*/
buildConcurrency?: number
/**
* @experimental
*
@ -240,4 +249,5 @@ export interface SiteConfig<ThemeConfig = any>
}
logger: Logger
userConfig: UserConfig
buildConcurrency: number
}

@ -113,6 +113,10 @@ export function createTitle(siteData: SiteData, pageData: PageData): string {
const templateString = createTitleTemplate(siteData.title, template)
if (title === templateString.slice(3)) {
return title
}
return `${title}${templateString}`
}

@ -96,6 +96,16 @@ export namespace DefaultTheme {
*/
darkModeSwitchLabel?: string
/**
* @default 'Switch to light theme'
*/
lightModeSwitchTitle?: string
/**
* @default 'Switch to dark theme'
*/
darkModeSwitchTitle?: string
/**
* @default 'Menu'
*/
@ -345,6 +355,7 @@ export namespace DefaultTheme {
desc?: string
links?: SocialLink[]
sponsor?: string
actionText?: string
}
// outline -------------------------------------------------------------------

Loading…
Cancel
Save