Merge branch 'chore/vite-3' into clean-urls-for-alpha

pull/869/head
Georges Gomes 3 years ago committed by GitHub
commit f3727d7cc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -48,7 +48,7 @@ The easiest way to start testing out VitePress is to tweak the VitePress docs. Y
$ pnpm run docs
```
After executing the above command, visit http://localhost:3000 and try modifying the source code. You'll get live update.
After executing the above command, visit http://localhost:5173 and try modifying the source code. You'll get live update.
If you don't need docs site up and running, you may start VitePress local dev environment with `pnpm run dev`.

@ -1,17 +1,18 @@
name: Release
on:
push:
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Create Release
jobs:
build:
name: Create Release
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Checkout
uses: actions/checkout@v3
- name: Create Release for Tag
id: release_tag
uses: yyx990803/release-tag@master

@ -5,17 +5,17 @@ on: [push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16]
node-version: [14, 16, 18]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2.0.1
with:
version: 7.0.1
uses: pnpm/action-setup@v2
- name: Set node version to ${{ matrix.node_version }}
uses: actions/setup-node@v3

2
.gitignore vendored

@ -10,3 +10,5 @@ dist
node_modules
pnpm-global
TODOs.md
.temp
*.tgz

@ -1,5 +1,3 @@
/docs
/examples
*.css
*.md
*.vue

@ -59,9 +59,9 @@ function nav() {
{
text: 'Contributing',
link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md'
},
],
},
}
]
}
]
}

@ -32,7 +32,7 @@ $ yarn docs:build
$ yarn docs:serve
```
The `serve` command will boot up local static web server that serves the files from `.vitepress/dist` at `http://localhost:5000`. It's an easy way to check if the production build looks OK in your local environment.
The `serve` command will boot up local static web server that serves the files from `.vitepress/dist` at `http://localhost:4173`. It's an easy way to check if the production build looks OK in your local environment.
You may configure the port of the server by passing `--port` flag as an argument.

@ -31,26 +31,13 @@ $ yarn add --dev vitepress vue
::: details Getting missing peer deps warnings?
`@docsearch/js` has certain issues with its peer dependencies. If you see some commands failing due to them, you can try this workaround for now:
On Yarn v2/v3, add this inside your rc file (`.yarnrc.yml` by default):
```yaml
packageExtensions:
'@docsearch/react@*':
peerDependenciesMeta:
'@types/react':
optional: true
'react':
optional: true
'react-dom':
optional: true
```
On PNPM, add this in your `package.json`:
If using PNPM, add this in your `package.json`:
```json
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"@algolia/client-search",
"@types/react",
"react",
"react-dom"
@ -89,7 +76,7 @@ Serve the documentation site in the local server.
$ yarn docs:dev
```
VitePress will start a hot-reloading development server at `http://localhost:3000`.
VitePress will start a hot-reloading development server at `http://localhost:5173`.
## Step. 4: Add more pages
@ -103,7 +90,7 @@ Let's add another page to the site. Create a file name `getting-started.md` alon
└─ package.json
```
Then, try to access `http://localhost:3000/getting-started` and you should see the content of `getting-started` is shown.
Then, try to access `http://localhost:5173/getting-started.html` and you should see the content of `getting-started` is shown.
This is how VitePress works basically. The directory structure corresponds with the URL path. You add files, and just try to access it.

@ -38,6 +38,7 @@ interface Theme {
Layout: Component // Vue 3 component
NotFound?: Component
enhanceApp?: (ctx: EnhanceAppContext) => void
setup?: () => void
}
interface EnhanceAppContext {
@ -65,6 +66,11 @@ export default {
// router is VitePress' custom router. `siteData` is
// a `ref` of current site-level metadata.
}
setup() {
// this function will be executed inside VitePressApp's
// setup hook. all composition APIs are available here.
}
}
```

@ -3,7 +3,7 @@
"version": "1.0.0-alpha.4",
"description": "Vite & Vue powered static site generator",
"type": "module",
"packageManager": "pnpm@7.1.7",
"packageManager": "pnpm@7.5.0",
"main": "dist/node/index.js",
"types": "types/index.d.ts",
"exports": {
@ -51,7 +51,7 @@
"dev-watch": "node scripts/watchAndCopy",
"build": "run-s build-prepare build-client build-node",
"build-prepare": "rimraf dist && node scripts/copyShared",
"build-client": "tsc -p src/client && node scripts/copyClient",
"build-client": "vue-tsc --noEmit -p src/client && tsc -p src/client && node scripts/copyClient",
"build-node": "rollup --config rollup.config.ts --configPlugin esbuild",
"format": "prettier --check --write .",
"format-fail": "prettier --check .",
@ -71,75 +71,75 @@
"ci-docs": "run-s docs-build"
},
"dependencies": {
"@docsearch/css": "^3.0.0",
"@docsearch/js": "^3.0.0",
"@vitejs/plugin-vue": "^2.3.2",
"@vue/devtools-api": "^6.1.4",
"@vueuse/core": "^8.5.0",
"@docsearch/css": "^3.1.1",
"@docsearch/js": "^3.1.1",
"@vitejs/plugin-vue": "^3.0.0-beta.0",
"@vue/devtools-api": "^6.2.0",
"@vueuse/core": "^8.7.5",
"body-scroll-lock": "^4.0.0-beta.0",
"shiki": "^0.10.1",
"vite": "^2.9.7",
"vue": "^3.2.33"
"vite": "^3.0.0-beta.0",
"vue": "^3.2.37"
},
"devDependencies": {
"@rollup/plugin-alias": "^3.1.5",
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-commonjs": "^22.0.1",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0",
"@types/body-scroll-lock": "^3.1.0",
"@types/compression": "^1.7.0",
"@types/compression": "^1.7.2",
"@types/cross-spawn": "^6.0.2",
"@types/debug": "^4.1.7",
"@types/fs-extra": "^9.0.11",
"@types/koa": "^2.13.1",
"@types/koa-static": "^4.0.1",
"@types/lru-cache": "^5.1.0",
"@types/markdown-it": "^12.0.1",
"@types/fs-extra": "^9.0.13",
"@types/koa": "^2.13.4",
"@types/koa-static": "^4.0.2",
"@types/markdown-it": "^12.2.3",
"@types/micromatch": "^4.0.2",
"@types/minimist": "^1.2.2",
"@types/node": "^15.6.1",
"@types/polka": "^0.5.3",
"@types/node": "^18.0.0",
"@types/polka": "^0.5.4",
"@types/prompts": "^2.0.14",
"chokidar": "^3.5.1",
"chokidar": "^3.5.3",
"compression": "^1.7.4",
"conventional-changelog-cli": "^2.1.1",
"conventional-changelog-cli": "^2.2.2",
"cross-spawn": "^7.0.3",
"debug": "^4.3.2",
"debug": "^4.3.4",
"diacritics": "^1.3.0",
"enquirer": "^2.3.6",
"esbuild": "^0.14.0",
"esbuild": "^0.14.48",
"escape-html": "^1.0.3",
"execa": "^6.1.0",
"fast-glob": "^3.2.7",
"fs-extra": "^10.0.0",
"fast-glob": "^3.2.11",
"fs-extra": "^10.1.0",
"gray-matter": "^4.0.3",
"lint-staged": "^11.0.0",
"lru-cache": "^6.0.0",
"markdown-it": "^12.3.2",
"markdown-it-anchor": "^8.4.1",
"markdown-it-attrs": "^4.1.3",
"lint-staged": "^13.0.3",
"lru-cache": "^7.12.0",
"markdown-it": "^13.0.1",
"markdown-it-anchor": "^8.6.4",
"markdown-it-attrs": "^4.1.4",
"markdown-it-container": "^3.0.0",
"markdown-it-emoji": "^2.0.0",
"markdown-it-emoji": "^2.0.2",
"markdown-it-toc-done-right": "^4.2.0",
"micromatch": "^4.0.4",
"minimist": "^1.2.5",
"micromatch": "^4.0.5",
"minimist": "^1.2.6",
"npm-run-all": "^4.1.5",
"ora": "^5.4.0",
"ora": "^5.4.1",
"picocolors": "^1.0.0",
"polka": "^0.5.2",
"prettier": "^2.3.0",
"prettier": "^2.7.1",
"prompts": "^2.4.2",
"rimraf": "^3.0.2",
"rollup": "^2.56.3",
"rollup": "^2.75.7",
"rollup-plugin-dts": "^4.2.2",
"rollup-plugin-esbuild": "^4.8.2",
"semver": "^7.3.5",
"simple-git-hooks": "^2.7.0",
"sirv": "^1.0.12",
"rollup-plugin-esbuild": "^4.9.1",
"semver": "^7.3.7",
"simple-git-hooks": "^2.8.0",
"sirv": "^2.0.2",
"supports-color": "^9.2.2",
"typescript": "^4.7.2",
"vitest": "^0.14.2"
"typescript": "^4.7.4",
"vitest": "^0.16.0",
"vue-tsc": "^0.38.2"
},
"pnpm": {
"peerDependencyRules": {

File diff suppressed because it is too large Load Diff

@ -49,7 +49,7 @@ export function usePrefetch() {
return
}
const rIC = (window as any).requestIdleCallback || setTimeout
const rIC = window.requestIdleCallback || setTimeout
let observer: IntersectionObserver | null = null
const observeLinks = () => {
@ -73,8 +73,8 @@ export function usePrefetch() {
})
rIC(() => {
document.querySelectorAll('#app a').forEach((link) => {
const { target, hostname, pathname } = link as HTMLAnchorElement
document.querySelectorAll<HTMLAnchorElement>('#app a').forEach((link) => {
const { target, hostname, pathname } = link
const extMatch = pathname.match(/\.\w+$/)
if (extMatch && extMatch[0] !== '.html') {
return

@ -2,11 +2,12 @@ import {
App,
createApp as createClientApp,
createSSRApp,
defineComponent,
h,
onMounted,
watch
} from 'vue'
import Theme from '/@theme/index'
import Theme from '../theme-default'
import { inBrowser, pathToFile } from './utils'
import { Router, RouterSymbol, createRouter } from './router'
import { siteDataRef, useData } from './data'
@ -18,7 +19,7 @@ import { ClientOnly } from './components/ClientOnly'
const NotFound = Theme.NotFound || (() => '404 Not Found')
const VitePressApp = {
const VitePressApp = defineComponent({
name: 'VitePressApp',
setup() {
const { site } = useData()
@ -38,9 +39,11 @@ const VitePressApp = {
// in prod mode, enable intersectionObserver based pre-fetch
usePrefetch()
}
if (Theme.setup) Theme.setup()
return () => h(Theme.Layout)
}
}
})
export function createApp() {
const router = newRouter()

@ -34,7 +34,7 @@ interface PageModule {
}
export function createRouter(
loadPageModule: (path: string) => PageModule | Promise<PageModule>,
loadPageModule: (path: string) => Promise<PageModule>,
fallbackComponent?: Component
): Router {
const route = reactive(getDefaultRoute())
@ -61,16 +61,11 @@ export function createRouter(
const targetLoc = new URL(href, fakeHost)
const pendingPath = (latestPendingPath = targetLoc.pathname)
try {
let page = loadPageModule(pendingPath)
// only await if it returns a Promise - this allows sync resolution
// on initial render in SSR.
if ('then' in page && typeof page.then === 'function') {
page = await page
}
let page = await loadPageModule(pendingPath)
if (latestPendingPath === pendingPath) {
latestPendingPath = null
const { default: comp, __pageData } = page as PageModule
const { default: comp, __pageData } = page
if (!comp) {
throw new Error(`Invalid route component: ${comp}`)
}
@ -88,7 +83,7 @@ export function createRouter(
try {
target = document.querySelector(
decodeURIComponent(targetLoc.hash)
) as HTMLElement
)
} catch (e) {
console.warn(e)
}
@ -188,7 +183,6 @@ export function useRouter(): Router {
if (!router) {
throw new Error('useRouter() is called without provider.')
}
// @ts-ignore
return router
}
@ -197,7 +191,7 @@ export function useRoute(): Route {
}
function scrollTo(el: HTMLElement, hash: string, smooth = false) {
let target: Element | null = null
let target: HTMLElement | null = null
try {
target = el.classList.contains('header-anchor')
@ -214,12 +208,12 @@ function scrollTo(el: HTMLElement, hash: string, smooth = false) {
document.querySelector(offset)!.getBoundingClientRect().bottom + 24
}
const targetPadding = parseInt(
window.getComputedStyle(target as HTMLElement).paddingTop,
window.getComputedStyle(target).paddingTop,
10
)
const targetTop =
window.scrollY +
(target as HTMLElement).getBoundingClientRect().top -
target.getBoundingClientRect().top -
offset +
targetPadding
// only smooth scroll if distance is smaller than screen height.

@ -12,4 +12,5 @@ export interface Theme {
Layout: Component
NotFound?: Component
enhanceApp?: (ctx: EnhanceAppContext) => void
setup?: () => void
}

@ -35,7 +35,8 @@ export function pathToFile(path: string): string {
// /foo/bar.html -> ./foo_bar.md
if (inBrowser) {
const base = import.meta.env.BASE_URL
pagePath = pagePath.slice(base.length).replace(/\//g, '_') + '.md'
pagePath =
(pagePath.slice(base.length).replace(/\//g, '_') || 'index') + '.md'
// client production build needs to account for page hash, which is
// injected directly in the page's html
const pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()]

@ -14,9 +14,3 @@ declare module '@siteData' {
const data: SiteData
export default data
}
// this module's typing is broken.
declare module '@docsearch/js' {
function docsearch<T = any>(props: T): void
export default docsearch
}

@ -29,14 +29,16 @@ function poll() {
}, 16)
}
type DocSearchProps = Parameters<typeof docsearch>[0]
function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
// note: multi-lang search support is removed since the theme
// doesn't support multiple locales as of now.
const options = Object.assign({}, userOptions, {
const options = Object.assign<{}, {}, DocSearchProps>({}, userOptions, {
container: '#docsearch',
navigator: {
navigate({ itemUrl }: { itemUrl: string }) {
navigate({ itemUrl }) {
const { pathname: hitPathname } = new URL(
window.location.origin + itemUrl
)
@ -51,7 +53,7 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
}
},
transformItems(items: any[]) {
transformItems(items) {
return items.map((item) => {
return Object.assign({}, item, {
url: getRelativePath(item.url)
@ -59,9 +61,10 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
})
},
hitComponent({ hit, children }: { hit: any; children: any }) {
// @ts-ignore
hitComponent({ hit, children }) {
const relativeHit = hit.url.startsWith('http')
? getRelativePath(hit.url as string)
? getRelativePath(hit.url)
: hit.url
return {

@ -22,7 +22,7 @@ const resolvedHeaders = computed(() => {
function handleClick({ target: el }: Event) {
const id = '#' + (el as HTMLAnchorElement).href!.split('#')[1]
const heading = document.querySelector(id) as HTMLAnchorElement
const heading = document.querySelector<HTMLAnchorElement>(id)
heading?.focus()
}
</script>

@ -1,18 +1,8 @@
<script setup lang="ts">
import type { Sponsors } from './VPSponsors.vue'
import type { Sponsor } from './VPSponsorsGrid.vue'
import VPSponsors from './VPSponsors.vue'
export interface Sponsors {
tier?: string
size?: 'xmini' | 'mini' | 'small'
items: Sponsor[]
}
export interface Sponsor {
name: string
img: string
url: string
}
defineProps<{
tier?: string
size?: 'xmini' | 'mini' | 'small'
@ -22,11 +12,6 @@ defineProps<{
<template>
<div class="VPDocAsideSponsors">
<VPSponsors
mode="aside"
:tier="tier"
:size="size"
:data="data"
/>
<VPSponsors mode="aside" :tier="tier" :size="size" :data="data" />
</div>
</template>

@ -8,9 +8,9 @@ const backToTop = ref()
watch(() => route.path, () => backToTop.value.focus())
function focusOnTargetAnchor({ target }: Event) {
const el = document.querySelector(
(target as HTMLAnchorElement).hash!
) as HTMLAnchorElement
const el = document.querySelector<HTMLAnchorElement>(
(target as HTMLAnchorElement).hash
)
if (el) {
const removeTabIndex = () => {

@ -1,40 +1,34 @@
<script setup lang="ts">
import type { GridSize } from '../composables/sponsor-grid'
import type { Sponsor } from './VPSponsorsGrid.vue'
import { computed } from 'vue'
import VPSponsorsGrid from './VPSponsorsGrid.vue'
export interface Sponsors {
tier?: string
size?: 'small' | 'medium' | 'big'
size?: GridSize
items: Sponsor[]
}
export interface Sponsor {
name: string
img: string
url: string
}
const props = defineProps<{
mode?: 'normal' | 'aside'
tier?: string
size?: 'xmini' | 'small' | 'medium' | 'big'
size?: GridSize
data: Sponsors[] | Sponsor[]
}>()
const sponsors = computed(() => {
const isSponsors = props.data.some((s) => {
return !!(s as Sponsors).items
return 'items' in s
})
if (isSponsors) {
return props.data
return props.data as Sponsors[]
}
return [{
tier: props.tier,
size: props.size,
items: props.data
}]
return [
{ tier: props.tier, size: props.size, items: props.data as Sponsor[] }
]
})
</script>

@ -1,4 +1,5 @@
<script setup lang="ts">
import type { GridSize } from '../composables/sponsor-grid'
import { ref } from 'vue'
import { useSponsorsGrid } from '../composables/sponsor-grid'
@ -9,7 +10,7 @@ export interface Sponsor {
}
const props = defineProps<{
size?: 'xmini' | 'mini' | 'small' | 'medium' | 'big'
size?: GridSize
data: Sponsor[]
}>()
@ -19,12 +20,29 @@ useSponsorsGrid({ el, size: props.size })
</script>
<template>
<div class="VPSponsorsGrid vp-sponsor-grid" :class="[props.size ?? 'medium']" ref="el">
<div v-for="sponsor in data" :key="sponsor.tier" class="vp-sponsor-grid-item">
<a class="vp-sponsor-grid-link" :href="sponsor.url" target="_blank" rel="sponsored noopener">
<div
class="VPSponsorsGrid vp-sponsor-grid"
:class="[props.size ?? 'medium']"
ref="el"
>
<div
v-for="sponsor in data"
:key="sponsor.name"
class="vp-sponsor-grid-item"
>
<a
class="vp-sponsor-grid-link"
:href="sponsor.url"
target="_blank"
rel="sponsored noopener"
>
<article class="vp-sponsor-grid-box">
<h4 class="visually-hidden">{{ sponsor.name }}</h4>
<img class="vp-sponsor-grid-image" :src="sponsor.img" :alt="sponsor.name" />
<img
class="vp-sponsor-grid-image"
:src="sponsor.img"
:alt="sponsor.name"
/>
</article>
</a>
</div>

@ -1,6 +1,6 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import type { DefaultTheme } from '..'
import VPTeamMembersItem from './VPTeamMembersItem.vue'
const props = defineProps<{

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { DefaultTheme } from '..'
import type { DefaultTheme } from 'vitepress/theme'
import VPIconHeart from './icons/VPIconHeart.vue'
import VPLink from './VPLink.vue'
import VPSocialLinks from './VPSocialLinks.vue'

@ -20,7 +20,7 @@ export function useFlyout(options: UseFlyoutOptions) {
listeners++
const unwatch = watch(focusedElement, (el) => {
if (el === options.el.value || options.el.value?.contains(el as Node)) {
if (el === options.el.value || options.el.value?.contains(el!)) {
focus.value = true
options.onFocus?.()
} else {

@ -135,7 +135,7 @@ export function useActiveAnchor(
if (hash !== null) {
prevActiveLink = container.value.querySelector(
`a[href="${decodeURIComponent(hash)}"]`
) as HTMLAnchorElement
)
}
const activeLink = prevActiveLink

@ -11,7 +11,6 @@
"lib": ["ESNext", "DOM"],
"types": ["vite/client"],
"paths": {
"/@theme/*": ["theme-default/*"],
"vitepress": ["index.ts"],
"vitepress/theme": ["../../types/default-theme.d"]
}

@ -1,9 +1,7 @@
import { createRequire } from 'module'
import { resolve, join } from 'path'
import { fileURLToPath } from 'url'
import { Alias, AliasOptions } from 'vite'
const require = createRequire(import.meta.url)
const PKG_ROOT = resolve(fileURLToPath(import.meta.url), '../..')
export const DIST_CLIENT_PATH = resolve(PKG_ROOT, 'client')
@ -17,29 +15,12 @@ export const DEFAULT_THEME_PATH = join(DIST_CLIENT_PATH, 'theme-default')
export const SITE_DATA_ID = '@siteData'
export const SITE_DATA_REQUEST_PATH = '/' + SITE_DATA_ID
const vueRuntimePath = 'vue/dist/vue.runtime.esm-bundler.js'
export function resolveAliases(root: string, themeDir: string): AliasOptions {
const paths: Record<string, string> = {
'/@theme': themeDir,
'@theme': themeDir,
[SITE_DATA_ID]: SITE_DATA_REQUEST_PATH
}
// prioritize vue installed in project root and fallback to
// vue that comes with vitepress itself.
let vuePath
try {
vuePath = require.resolve(vueRuntimePath, { paths: [root] })
} catch (e) {
vuePath = require.resolve(vueRuntimePath)
}
const aliases: Alias[] = [
...Object.keys(paths).map((p) => ({
find: p,
replacement: paths[p]
})),
{
find: SITE_DATA_ID,
replacement: SITE_DATA_REQUEST_PATH
},
{
find: /^vitepress$/,
replacement: join(DIST_CLIENT_PATH, '/index')
@ -52,12 +33,6 @@ export function resolveAliases(root: string, themeDir: string): AliasOptions {
{
find: /^vitepress\//,
replacement: PKG_ROOT + '/'
},
// make sure it always use the same vue dependency that comes
// with vitepress itself
{
find: /^vue$/,
replacement: vuePath
}
]

@ -84,7 +84,8 @@ export async function build(
pageToHashMap
)
} finally {
await fs.remove(siteConfig.tempDir)
if (!process.env.DEBUG)
fs.rmSync(siteConfig.tempDir, { recursive: true, force: true })
}
console.log(`build complete in ${((Date.now() - start) / 1000).toFixed(2)}s.`)

@ -52,9 +52,8 @@ export async function bundle(
pageToHashMap,
clientJSMap
),
// @ts-ignore
ssr: {
noExternal: ['vitepress']
noExternal: ['vitepress', '@docsearch/css']
},
build: {
...options,
@ -71,7 +70,11 @@ export async function bundle(
output: {
...rollupOptions?.output,
...(ssr
? {}
? {
entryFileNames: `[name].js`,
chunkFileNames: `[name].[hash].js`,
assetFileNames: `[name].[ext]`
}
: {
chunkFileNames(chunk) {
// avoid ads chunk being intercepted by adblock
@ -95,9 +98,7 @@ export async function bundle(
}
})
}
},
// minify with esbuild in MPA mode (for CSS)
minify: ssr ? (config.mpa ? 'esbuild' : false) : !process.env.DEBUG
}
}
})
@ -138,7 +139,7 @@ export async function bundle(
}
// build <script client> bundle
if (Object.keys(clientJSMap).length) {
clientResult = (await buildMPAClient(clientJSMap, config)) as RollupOutput
clientResult = await buildMPAClient(clientJSMap, config)
}
}
@ -167,7 +168,7 @@ function staticImportedByEntry(
importStack: string[] = []
): boolean {
if (cache.has(id)) {
return cache.get(id) as boolean
return !!cache.get(id)
}
if (importStack.includes(id)) {
// circular deps!

@ -1,4 +1,3 @@
import { createRequire } from 'module'
import fs from 'fs-extra'
import path from 'path'
import { pathToFileURL } from 'url'
@ -9,8 +8,6 @@ import { HeadConfig, PageData, createTitle, notFoundPageData } from '../shared'
import { slash } from '../utils/slash'
import { SiteConfig, resolveSiteDataByRoute } from '../config'
const require = createRequire(import.meta.url)
export async function renderPage(
config: SiteConfig,
page: string, // foo.md
@ -20,28 +17,16 @@ export async function renderPage(
pageToHashMap: Record<string, string>,
hashMapString: string
) {
const { createApp } = await import(
pathToFileURL(path.join(config.tempDir, `app.js`)).toString()
)
const entryPath = path.join(config.tempDir, 'app.js')
const { createApp } = await import(pathToFileURL(entryPath).toString())
const { app, router } = createApp()
const routePath = `/${page.replace(/\.md$/, '')}`
const siteData = resolveSiteDataByRoute(config.site, routePath)
router.go(routePath)
// lazy require server-renderer for production build
// prioritize project root over vitepress' own dep
let rendererPath
try {
rendererPath = require.resolve('vue/server-renderer', {
paths: [config.root]
})
} catch (e) {
rendererPath = require.resolve('vue/server-renderer')
}
await router.go(routePath)
// render page
const content = await import(pathToFileURL(rendererPath).toString()).then(
(r) => r.renderToString(app)
const content = await import('vue/server-renderer').then(
({ renderToString: r }) => r(app)
)
const pageName = page.replace(/\//g, '_')

@ -199,7 +199,7 @@ async function resolveUserConfig(
}
const userConfig: RawConfigExports = configPath
? ((
? (
await loadConfigFromFile(
{
command,
@ -208,7 +208,7 @@ async function resolveUserConfig(
configPath,
root
)
)?.config as any)
)?.config!
: {}
if (configPath) {

@ -219,6 +219,14 @@ export async function createVitePressPlugin(
delete bundle[name]
}
}
if (config.ssr?.format === 'esm') {
this.emitFile({
type: 'asset',
fileName: 'package.json',
source: '{ "private": true, "type": "module" }'
})
}
} else {
// client build:
// for each .md entry chunk, adjust its name to its correct path.

@ -22,7 +22,7 @@ export interface ServeOptions {
}
export async function serve(options: ServeOptions = {}) {
const port = options.port !== undefined ? options.port : 5000
const port = options.port !== undefined ? options.port : 4173
const site = await resolveConfig(options.root, 'serve', 'production')
const base = trimChar(options?.base ?? site?.site?.base ?? '', '/')

@ -1,3 +1,4 @@
import { setDefaultResultOrder } from 'node:dns'
import { createServer as createViteServer, ServerOptions } from 'vite'
import { resolveConfig } from './config'
import { createVitePressPlugin } from './plugin'
@ -13,6 +14,8 @@ export async function createServer(
delete serverOptions.base
}
setDefaultResultOrder('verbatim')
return createViteServer({
root: config.srcDir,
base: config.site.base,

@ -13,7 +13,6 @@ export type {
export const EXTERNAL_URL_RE = /^https?:/i
export const APPEARANCE_KEY = 'vitepress-theme-appearance'
// @ts-ignore
export const inBrowser = typeof window !== 'undefined'
export const notFoundPageData: PageData = {

18
theme.d.ts vendored

@ -1,14 +1,14 @@
// so that users can do `import DefaultTheme from 'vitepress/theme'`
import { ComponentOptions } from 'vue'
import type { ComponentOptions } from 'vue'
export const VPHomeHero = ComponentOptions
export const VPHomeFeatures = ComponentOptions
export const VPHomeSponsors = ComponentOptions
export const VPDocAsideSponsors = ComponentOptions
export const VPTeamPage = ComponentOptions
export const VPTeamPageTitle = ComponentOptions
export const VPTeamPageSection = ComponentOptions
export const VPTeamMembers = ComponentOptions
export const VPHomeHero: ComponentOptions
export const VPHomeFeatures: ComponentOptions
export const VPHomeSponsors: ComponentOptions
export const VPDocAsideSponsors: ComponentOptions
export const VPTeamPage: ComponentOptions
export const VPTeamPageTitle: ComponentOptions
export const VPTeamPageSection: ComponentOptions
export const VPTeamMembers: ComponentOptions
declare const theme: {
Layout: ComponentOptions

Loading…
Cancel
Save