diff --git a/lib/app/Content.js b/lib/app/components/Content.js
similarity index 85%
rename from lib/app/Content.js
rename to lib/app/components/Content.js
index 6d76ef4b..1b3909be 100644
--- a/lib/app/Content.js
+++ b/lib/app/components/Content.js
@@ -1,7 +1,8 @@
import { h, shallowRef, watchEffect, inject, nextTick } from 'vue'
-import { RouteSymbol } from './router'
+import { RouteSymbol } from '../composables/router'
+import Theme from '/@theme/index'
-const Default404 = () => '404 Not Found'
+const NotFound = Theme.NotFound || (() => '404 Not Found')
export const Content = {
setup() {
@@ -35,7 +36,7 @@ export const Content = {
})
.catch((err) => {
if (route.path === pendingPath) {
- comp.value = Default404
+ comp.value = NotFound
}
})
})
diff --git a/lib/app/composables/data.js b/lib/app/composables/data.js
new file mode 100644
index 00000000..a2c575b9
--- /dev/null
+++ b/lib/app/composables/data.js
@@ -0,0 +1,11 @@
+export function useSiteData() {
+ return {
+ msg: 'this is site'
+ }
+}
+
+export function usePageData() {
+ return {
+ msg: 'this is page'
+ }
+}
diff --git a/lib/app/router.js b/lib/app/composables/router.js
similarity index 100%
rename from lib/app/router.js
rename to lib/app/composables/router.js
diff --git a/lib/app/exports.js b/lib/app/exports.js
new file mode 100644
index 00000000..b21a1942
--- /dev/null
+++ b/lib/app/exports.js
@@ -0,0 +1,3 @@
+// exports in this file are exposed to themes and md files via 'vitepress'
+// so the user can do `import { usePageData } from 'vitepress'`
+export { usePageData, useSiteData } from './composables/data'
diff --git a/lib/app/index.js b/lib/app/index.js
index 5267b384..83753d74 100644
--- a/lib/app/index.js
+++ b/lib/app/index.js
@@ -1,7 +1,8 @@
import { createApp, h } from 'vue'
-import { Layout } from '/@theme/index'
-import { Content } from './Content'
-import { useRouter } from './router'
+import { Content } from './components/Content'
+import { useRouter } from './composables/router'
+import { useSiteData } from './composables/data'
+import Theme from '/@theme/index'
const App = {
setup() {
@@ -10,12 +11,16 @@ const App = {
} else {
// TODO inject static route for SSR
}
- return () => h(Layout)
+ return () => h(Theme.Layout)
}
}
const app = createApp(App)
+Object.defineProperty(app.config.globalProperties, '$site', {
+ get: useSiteData
+})
+
app.component('Content', Content)
app.mount('#app')
diff --git a/lib/jsconfig.json b/lib/jsconfig.json
index 6f38c88b..7176ac8c 100644
--- a/lib/jsconfig.json
+++ b/lib/jsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "baseUrl": "../",
"lib": ["ESNext", "DOM"],
"moduleResolution": "node",
"checkJs": true,
@@ -8,7 +9,8 @@
"noImplicitAny": true,
"paths": {
"/@app/*": ["lib/app/*"],
- "/@theme/*": ["lib/theme-default/*"]
+ "/@theme/*": ["lib/theme-default/*"],
+ "vitepress": ["lib/app/exports.js"]
}
},
"include": ["."]
diff --git a/lib/theme-default/Layout.vue b/lib/theme-default/Layout.vue
index dc01f311..54dd80e1 100644
--- a/lib/theme-default/Layout.vue
+++ b/lib/theme-default/Layout.vue
@@ -1,13 +1,22 @@
-
Hello VitePress {{ a }}
+
Hello VitePress
+
{{ $site }}
+
{{ $page }}
+
{{ site }}
+
{{ page }}
diff --git a/lib/theme-default/index.js b/lib/theme-default/index.js
index 4763bbc2..964ac493 100644
--- a/lib/theme-default/index.js
+++ b/lib/theme-default/index.js
@@ -1,3 +1,13 @@
import Layout from './Layout.vue'
-export { Layout }
+/**
+ * @type {{
+ * Layout: import('vue').ComponentOptions
+ * NotFound?: import('vue').ComponentOptions
+ * }}
+ */
+const Theme = {
+ Layout
+}
+
+export default Theme
diff --git a/src/server.ts b/src/server.ts
index 0b39e6c7..c3567d79 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -38,7 +38,7 @@ function createVitePressPlugin({
app.use(async (ctx, next) => {
// handle .md -> vue transforms
if (ctx.path.endsWith('.md')) {
- const file = resolver.publicToFile(ctx.path)
+ const file = resolver.requestToFile(ctx.path)
await cachedRead(ctx, file)
// let vite know this is supposed to be treated as vue file
ctx.vue = true
@@ -48,7 +48,7 @@ function createVitePressPlugin({
}
// detect and serve vitepress @app / @theme files
- const file = vitepressResolver.publicToFile(ctx.path, root)
+ const file = vitepressResolver.requestToFile(ctx.path, root)
if (file) {
await cachedRead(ctx, file)
debug(ctx.url, ctx.status)
diff --git a/src/tsconfig.json b/src/tsconfig.json
index a045e381..f87a6b82 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "baseUrl": ".",
+ "baseUrl": "../",
"outDir": "../dist",
"module": "commonjs",
"lib": ["ESNext"],
diff --git a/src/utils/pathResolver.ts b/src/utils/pathResolver.ts
index 81cf023d..7b4ef089 100644
--- a/src/utils/pathResolver.ts
+++ b/src/utils/pathResolver.ts
@@ -10,7 +10,7 @@ export const APP_PATH = path.join(__dirname, '../../lib/app')
// vite HMR can send the correct update notifications to the client.
export function createResolver(themePath: string): Resolver {
return {
- publicToFile(publicPath) {
+ requestToFile(publicPath) {
if (publicPath.startsWith('/@app')) {
return path.join(APP_PATH, publicPath.replace(/^\/@app\/?/, ''))
}
@@ -18,13 +18,18 @@ export function createResolver(themePath: string): Resolver {
return path.join(themePath, publicPath.replace(/^\/@theme\/?/, ''))
}
},
- fileToPublic(filePath) {
+ fileToRequest(filePath) {
if (filePath.startsWith(APP_PATH)) {
return `/@app/${path.relative(APP_PATH, filePath)}`
}
if (filePath.startsWith(themePath)) {
return `/@theme/${path.relative(themePath, filePath)}`
}
+ },
+ idToRequest(id) {
+ if (id === 'vitepress') {
+ return '/@app/exports.js'
+ }
}
}
}