From 42bac424fe7fc94679c7070dacb90edc6cc2d5f5 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 May 2020 20:59:33 -0400 Subject: [PATCH] wip: lean builds --- lib/app/index.js | 19 +++++++++++++++++-- lib/shim.d.ts | 1 + src/build/bundle.ts | 15 +++++++++++++++ src/build/render.ts | 4 +++- src/markdown/markdown.ts | 1 + src/markdownToVue.ts | 5 +++-- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/app/index.js b/lib/app/index.js index 825503f3..241dc644 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -34,11 +34,22 @@ export function createApp() { }) } + let isInitialPageLoad = inBrowser + /** + * @type string + */ + let initialPath + const router = createRouter((route) => { let pagePath = route.path.replace(/\.html$/, '') if (pagePath.endsWith('/')) { pagePath += 'index' } + + if (isInitialPageLoad) { + initialPath = pagePath + } + if (__DEV__) { // awlays force re-fetch content in dev pagePath += `.md?t=${Date.now()}` @@ -46,11 +57,15 @@ export function createApp() { // in production, each .md file is built into a .md.js file following // the path conversion scheme. // /foo/bar.html -> /js/foo_bar.md.js - // TODO handle base - pagePath = './' + pagePath.slice(1).replace(/\//g, '_') + '.md.js' + const useLeanBuild = isInitialPageLoad || initialPath === pagePath + pagePath = + (inBrowser ? __BASE__ + '_assets/' : './') + + pagePath.slice(1).replace(/\//g, '_') + + (useLeanBuild ? '.md.lean.js' : '.md.js') } if (inBrowser) { + isInitialPageLoad = false // in browser: native dynamic import return import(pagePath).then((page) => { if (page.__pageData) { diff --git a/lib/shim.d.ts b/lib/shim.d.ts index 09299509..52bc0549 100644 --- a/lib/shim.d.ts +++ b/lib/shim.d.ts @@ -1,4 +1,5 @@ declare const __DEV__: boolean +declare const __BASE__: string declare module '*.vue' { import { ComponentOptions } from 'vue' diff --git a/src/build/bundle.ts b/src/build/bundle.ts index 8880e26e..75586008 100644 --- a/src/build/bundle.ts +++ b/src/build/bundle.ts @@ -22,6 +22,8 @@ export async function bundle( const resolver = createResolver(config.themeDir) const markdownToVue = createMarkdownToVueRenderFn(root) + let isClientBuild = true + const VitePressPlugin: Plugin = { name: 'vitepress', resolveId(id) { @@ -58,6 +60,18 @@ export async function bundle( /\//g, '_' ) + '.js' + + if (isClientBuild) { + // inject another chunk with the content stripped + bundle[name + '-lean'] = { + ...chunk, + fileName: chunk.fileName.replace(/\.js$/, '.lean.js'), + code: chunk.code.replace( + /createStaticVNode\([^)]+, (\d+)\)/g, + `createStaticVNode("", $1)` + ) + } + } } } } @@ -99,6 +113,7 @@ export async function bundle( const clientResult = await build(viteOptions) console.log('building server bundle...') + isClientBuild = false const serverResult = await ssrBuild({ ...viteOptions, outDir: config.tempDir diff --git a/src/build/render.ts b/src/build/render.ts index 88623c5f..b4c830e5 100644 --- a/src/build/render.ts +++ b/src/build/render.ts @@ -40,7 +40,9 @@ export async function renderPage( // them as well so we fetch everything as early as possible without having // to wait for entry chunks to parse ...resolvePageImports(config, page, result), - pageJsFileName, + // for any initial page load, we only need the lean version of the page js + // since the static content is already on the page! + pageJsFileName.replace(/\.js$/, '.lean.js'), 'index.js' ] .map((file) => { diff --git a/src/markdown/markdown.ts b/src/markdown/markdown.ts index b8cb8809..533a8c99 100644 --- a/src/markdown/markdown.ts +++ b/src/markdown/markdown.ts @@ -45,6 +45,7 @@ export const createMarkdownRenderer = ( ): MarkdownRenderer => { const md = MarkdownIt({ html: true, + linkify: true, highlight, ...options }) diff --git a/src/markdownToVue.ts b/src/markdownToVue.ts index 50cf520e..885669f7 100644 --- a/src/markdownToVue.ts +++ b/src/markdownToVue.ts @@ -51,8 +51,9 @@ export function createMarkdownToVueRenderFn( : data.hoistedTags || [] const vueSrc = - `\n` + - additionalBlocks.join('\n') + additionalBlocks.join('\n') + + `\n` + debug(`[render] ${file} in ${Date.now() - start}ms.`) const result = { vueSrc, pageData }