pull/1/head
Evan You 5 years ago
parent 26c4d5eaa9
commit 24bac77eec

@ -1,7 +1,17 @@
import { createApp, ref, provide, h } from 'vue' import {
createApp,
ref,
h,
provide,
inject,
watchEffect,
shallowRef
} from 'vue'
import { Layout } from '/@theme/index.js' import { Layout } from '/@theme/index.js'
const app = createApp({ const PathSymbol = Symbol()
const App = {
setup() { setup() {
const path = ref(window.location.pathname) const path = ref(window.location.pathname)
@ -14,10 +24,42 @@ const app = createApp({
// } // }
// }) // })
provide('vitepress:path', path) provide(PathSymbol, path)
return () => h(Layout) return () => h(Layout)
} }
}
const Default404 = () => '404 Not Found'
const Content = {
setup() {
const path = inject(PathSymbol)
const comp = shallowRef()
watchEffect(() => {
let pagePath = path.value.replace(/\.html$/, '')
if (pagePath.endsWith('/')) {
pagePath += 'index.md'
} else {
pagePath += '.md'
}
import(pagePath)
.then((m) => {
comp.value = m.default
}) })
.catch(err => {
comp.value = Default404
})
})
return () => (comp.value ? h(comp.value) : null)
}
}
const app = createApp(App)
app.component('Content', Content)
app.mount('#app') app.mount('#app')

@ -0,0 +1,3 @@
export function markdownToVue(content: string): string {
return `<template>${content}</template>`
}

@ -1,10 +1,12 @@
import path from 'path' import path from 'path'
import { promises as fs } from 'fs'
import { import {
createServer as createViteServer, createServer as createViteServer,
cachedRead, cachedRead,
Plugin, Plugin,
Resolver Resolver
} from 'vite' } from 'vite'
import { markdownToVue } from './markdown'
const debug = require('debug')('vitepress') const debug = require('debug')('vitepress')
@ -32,34 +34,46 @@ const VitePressResolver: Resolver = {
} }
} }
const VitePressPlugin: Plugin = ({ app, root, watcher }) => { const VitePressPlugin: Plugin = ({ app, root, watcher, resolver }) => {
// watch theme files if it's outside of project root // watch theme files if it's outside of project root
if (path.relative(root, themePath).startsWith('..')) { if (path.relative(root, themePath).startsWith('..')) {
debug(`watching theme dir outside of project root: ${themePath}`) debug(`watching theme dir outside of project root: ${themePath}`)
watcher.add(themePath) watcher.add(themePath)
} }
// hot reload .md files as .vue files
watcher.on('change', async (file) => {
if (file.endsWith('.md')) {
const content = await fs.readFile(file, 'utf-8')
watcher.handleVueReload(file, Date.now(), markdownToVue(content))
}
})
app.use(async (ctx, next) => { app.use(async (ctx, next) => {
if (ctx.path.endsWith('.md')) {
await cachedRead(ctx, resolver.publicToFile(ctx.path))
// let vite know this is supposed to be treated as vue file
ctx.vue = true
ctx.body = markdownToVue(ctx.body)
debug(`serving ${ctx.url}`)
return next()
}
// detect and serve vitepress files // detect and serve vitepress files
const file = VitePressResolver.publicToFile(ctx.path, root) const file = VitePressResolver.publicToFile(ctx.path, root)
if (file) { if (file) {
ctx.type = path.extname(file) ctx.type = path.extname(file)
ctx.body = await cachedRead(file) await cachedRead(ctx, file)
debug(`serving file: ${ctx.url}`) debug(`serving file: ${ctx.url}`)
return next() return next()
} }
if (ctx.path.endsWith('.md')) {
debug(`serving .md: ${ctx.path}`)
}
await next() await next()
// serve our index.html after vite history fallback // serve our index.html after vite history fallback
if (ctx.url === '/index.html') { if (ctx.url === '/index.html') {
ctx.type = 'text/html' await cachedRead(ctx, path.join(appPath, 'index-dev.html'))
ctx.body = await cachedRead(path.join(appPath, 'index-dev.html'))
} }
}) })
} }

@ -1,3 +1,11 @@
<template> <template>
hello world <div class="theme-container">
<Content/>
</div>
</template> </template>
<style>
.theme-container {
font-family: Arial, Helvetica, sans-serif;
}
</style>

Loading…
Cancel
Save