2021-03-01 15:06:11 +08:00

94 lines
3.2 KiB
JavaScript

import { createApp as createClientApp, createSSRApp } from 'vue';
import { createRouter, RouterSymbol } from './router';
import { useUpdateHead } from './composables/head';
import { Content } from './components/Content';
import Debug from './components/Debug.vue';
import Theme from '/@theme/index';
import { inBrowser, pathToFile } from './utils';
import { useSiteDataByRoute } from './composables/siteDataByRoute';
import { siteDataRef } from './composables/siteData';
const NotFound = Theme.NotFound || (() => '404 Not Found');
export function createApp() {
let isInitialPageLoad = inBrowser;
let initialPath;
const router = createRouter((path) => {
let pageFilePath = pathToFile(path);
if (isInitialPageLoad) {
initialPath = pageFilePath;
}
// use lean build if this is the initial page load or navigating back
// to the initial loaded path (the static vnodes already adopted the
// static content on that load so no need to re-fetch the page)
if (isInitialPageLoad || initialPath === pageFilePath) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js');
}
if (inBrowser) {
isInitialPageLoad = false;
// in browser: native dynamic import
return import(/*@vite-ignore*/ pageFilePath);
}
else {
// SSR, sync require
return require(pageFilePath);
}
}, NotFound);
// update route.data on HMR updates of active page
if (import.meta.hot) {
// hot reload pageData
import.meta.hot.on('vitepress:pageData', (payload) => {
if (payload.path.replace(/(\bindex)?\.md$/, '') ===
location.pathname.replace(/(\bindex)?\.html$/, '')) {
router.route.data = payload.pageData;
}
});
}
const app = process.env.NODE_ENV === 'production'
? createSSRApp(Theme.Layout)
: createClientApp(Theme.Layout);
app.provide(RouterSymbol, router);
app.component('Content', Content);
app.component('Debug', process.env.NODE_ENV === 'production' ? () => null : Debug);
const siteDataByRouteRef = useSiteDataByRoute(router.route);
if (inBrowser) {
// dynamically update head tags
useUpdateHead(router.route, siteDataByRouteRef);
}
Object.defineProperties(app.config.globalProperties, {
$site: {
get() {
return siteDataRef.value;
}
},
$siteByRoute: {
get() {
return siteDataByRouteRef.value;
}
},
$page: {
get() {
return router.route.data;
}
},
$theme: {
get() {
return siteDataByRouteRef.value.themeConfig;
}
}
});
if (Theme.enhanceApp) {
Theme.enhanceApp({
app,
router,
siteData: siteDataByRouteRef
});
}
return { app, router };
}
if (inBrowser) {
const { app, router } = createApp();
// wait unitl page component is fetched before mounting
router.go().then(() => {
app.mount('#app');
});
}