From 24bac77eecf606db8f7a38899b42e91598f8d3c9 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 26 Apr 2020 23:40:18 -0400 Subject: [PATCH] it works! --- lib/app/index.js | 50 +++++++++++++++++++++++++++++++++--- lib/markdown.ts | 3 +++ lib/server.ts | 30 ++++++++++++++++------ lib/theme-default/Layout.vue | 10 +++++++- 4 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 lib/markdown.ts diff --git a/lib/app/index.js b/lib/app/index.js index 78aa8a0e..71e87e3c 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -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' -const app = createApp({ +const PathSymbol = Symbol() + +const App = { setup() { const path = ref(window.location.pathname) @@ -14,10 +24,42 @@ const app = createApp({ // } // }) - provide('vitepress:path', path) + provide(PathSymbol, path) 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') diff --git a/lib/markdown.ts b/lib/markdown.ts new file mode 100644 index 00000000..71f9c4d2 --- /dev/null +++ b/lib/markdown.ts @@ -0,0 +1,3 @@ +export function markdownToVue(content: string): string { + return `` +} diff --git a/lib/server.ts b/lib/server.ts index 740718f0..0a1d88d4 100644 --- a/lib/server.ts +++ b/lib/server.ts @@ -1,10 +1,12 @@ import path from 'path' +import { promises as fs } from 'fs' import { createServer as createViteServer, cachedRead, Plugin, Resolver } from 'vite' +import { markdownToVue } from './markdown' 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 if (path.relative(root, themePath).startsWith('..')) { debug(`watching theme dir outside of project root: ${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) => { + 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 const file = VitePressResolver.publicToFile(ctx.path, root) if (file) { ctx.type = path.extname(file) - ctx.body = await cachedRead(file) + await cachedRead(ctx, file) debug(`serving file: ${ctx.url}`) return next() } - if (ctx.path.endsWith('.md')) { - debug(`serving .md: ${ctx.path}`) - } - await next() // serve our index.html after vite history fallback if (ctx.url === '/index.html') { - ctx.type = 'text/html' - ctx.body = await cachedRead(path.join(appPath, 'index-dev.html')) + await cachedRead(ctx, path.join(appPath, 'index-dev.html')) } }) } diff --git a/lib/theme-default/Layout.vue b/lib/theme-default/Layout.vue index 2f791384..53fad0bf 100644 --- a/lib/theme-default/Layout.vue +++ b/lib/theme-default/Layout.vue @@ -1,3 +1,11 @@ + +