hmr for pageData

pull/1/head
Evan You 4 years ago
parent cc2174a3c0
commit 32244a99a8

@ -1,5 +1,6 @@
import { shallowReactive, provide, inject, nextTick } from 'vue'
import Theme from '/@theme/index'
import { hot } from '@hmr'
const NotFound = Theme.NotFound || (() => '404 Not Found')
@ -29,6 +30,18 @@ export function useRouter() {
const loc = location
const route = shallowReactive(getDefaultRoute())
if (__DEV__) {
// hot reload pageData
hot.on('vitepress:pageData', (data) => {
if (
data.path.replace(/\.md$/, '') ===
location.pathname.replace(/\.html$/, '')
) {
route.pageData = data.pageData
}
})
}
window.addEventListener(
'click',
/**

@ -16,6 +16,8 @@ export function useSiteData() {
}
// hmr
hot.accept('/@siteData', (m) => {
siteDataRef.value = parse(m.default)
})
if (__DEV__) {
hot.accept('/@siteData', (m) => {
siteDataRef.value = parse(m.default)
})
}

@ -1,5 +1,6 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["ESNext", "DOM"],
"moduleResolution": "node",
"checkJs": true,
@ -7,9 +8,9 @@
"strictNullChecks": true,
"noImplicitAny": true,
"paths": {
"/@app/*": ["lib/app/*"],
"/@theme/*": ["lib/theme-default/*"],
"vitepress": ["lib/app/exports.js"]
"/@app/*": ["app/*"],
"/@theme/*": ["theme-default/*"],
"vitepress": ["app/exports.js"]
}
},
"include": ["."]

1
lib/shim.d.ts vendored

@ -14,5 +14,6 @@ declare module "@siteData" {
declare module "@hmr" {
export declare const hot: {
accept(path: string, cb: (module: any) => void)
on(event: string, cb: (data: any) => void)
}
}

@ -6,7 +6,19 @@ import { Header } from './markdown/plugins/header'
import { deeplyParseHeader } from './utils/parseHeader'
const debug = require('debug')('vitepress:md')
const cache = new LRUCache<string, string>({ max: 1024 })
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
interface MarkdownCompileResult {
vueSrc: string
pageData: PageData
}
export interface PageData {
title: string
frontmatter: Record<string, any>
headers: Header[]
lastUpdated: number
}
export function createMarkdownToVueRenderFn(
root: string,
@ -29,38 +41,36 @@ export function createMarkdownToVueRenderFn(
// TODO validate data.links?
// inject page data
const additionalBlocks = injectPageData(
data.hoistedTags || [],
content,
const pageData: PageData = {
title: inferTitle(frontmatter, content),
frontmatter,
data.headers || [],
headers: data.headers,
lastUpdated
}
const additionalBlocks = injectPageData(
data.hoistedTags || [],
pageData
)
const vueSrc =
`<template><div class="vitepress-content">${html}</div></template>\n` +
additionalBlocks.join('\n')
debug(`[render] ${file} in ${Date.now() - start}ms.`)
cache.set(src, vueSrc)
return vueSrc
const result = { vueSrc, pageData }
cache.set(src, result)
return result
}
}
const scriptRE = /<\/script>/
function injectPageData(
tags: string[],
content: string,
frontmatter: object,
headers: Header[],
lastUpdated: number
data: PageData
) {
const code = `\nexport const __pageData = ${JSON.stringify({
title: inferTitle(frontmatter, content),
frontmatter,
headers,
lastUpdated
})}`
const code = `\nexport const __pageData = ${JSON.stringify(data)}`
const existingScriptIndex = tags.findIndex((tag) => scriptRE.test(tag))
if (existingScriptIndex > -1) {
tags[existingScriptIndex] = tags[existingScriptIndex].replace(
@ -85,4 +95,5 @@ const inferTitle = (frontmatter: any, content: string) => {
if (match) {
return deeplyParseHeader(match[1].trim())
}
return ''
}

@ -44,11 +44,21 @@ function createVitePressPlugin(config: ResolvedConfig): Plugin {
debugHmr(`reloading ${file}`)
const content = await cachedRead(null, file)
const timestamp = Date.now()
watcher.handleVueReload(
file,
timestamp,
markdownToVue(content, file, timestamp)
)
const { pageData, vueSrc } = markdownToVue(content, file, timestamp)
// notify the client to update page data
watcher.send({
type: 'custom',
id: 'vitepress:pageData',
customData: {
path: resolver.fileToRequest(file),
pageData
},
timestamp: Date.now()
})
// reload the content component
watcher.handleVueReload(file, timestamp, vueSrc)
}
})
@ -90,7 +100,11 @@ function createVitePressPlugin(config: ResolvedConfig): Plugin {
await cachedRead(ctx, file)
// let vite know this is supposed to be treated as vue file
ctx.vue = true
ctx.body = markdownToVue(ctx.body, file, ctx.lastModified.getTime())
ctx.body = markdownToVue(
ctx.body,
file,
ctx.lastModified.getTime()
).vueSrc
debug(ctx.url, ctx.status)
return next()
}

Loading…
Cancel
Save