|
|
|
@ -34,14 +34,7 @@ export async function createMarkdownToVueRenderFn(
|
|
|
|
|
|
|
|
|
|
pages = pages.map((p) => slash(p.replace(/\.md$/, '')))
|
|
|
|
|
|
|
|
|
|
const userDefineRegex = userDefines
|
|
|
|
|
? new RegExp(
|
|
|
|
|
`\\b(${Object.keys(userDefines)
|
|
|
|
|
.map((key) => key.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'))
|
|
|
|
|
.join('|')})`,
|
|
|
|
|
'g'
|
|
|
|
|
)
|
|
|
|
|
: null
|
|
|
|
|
const replaceRegex = genReplaceRegexp(userDefines, isBuild)
|
|
|
|
|
|
|
|
|
|
return async (
|
|
|
|
|
src: string,
|
|
|
|
@ -74,24 +67,9 @@ export async function createMarkdownToVueRenderFn(
|
|
|
|
|
md.__path = file
|
|
|
|
|
md.__relativePath = relativePath
|
|
|
|
|
|
|
|
|
|
let html = md.render(content)
|
|
|
|
|
const html = md.render(content)
|
|
|
|
|
const data = md.__data
|
|
|
|
|
|
|
|
|
|
if (isBuild) {
|
|
|
|
|
// avoid env variables being replaced by vite
|
|
|
|
|
html = html
|
|
|
|
|
.replace(/\bimport\.meta/g, 'import.<wbr/>meta')
|
|
|
|
|
.replace(/\bprocess\.env/g, 'process.<wbr/>env')
|
|
|
|
|
|
|
|
|
|
// also avoid replacing vite user defines
|
|
|
|
|
if (userDefineRegex) {
|
|
|
|
|
html = html.replace(
|
|
|
|
|
userDefineRegex,
|
|
|
|
|
(_) => `${_[0]}<wbr/>${_.slice(1)}`
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate data.links
|
|
|
|
|
const deadLinks: string[] = []
|
|
|
|
|
const recordDeadLink = (url: string) => {
|
|
|
|
@ -149,8 +127,14 @@ export async function createMarkdownToVueRenderFn(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const vueSrc =
|
|
|
|
|
genPageDataCode(data.hoistedTags || [], pageData).join('\n') +
|
|
|
|
|
`\n<template><div>${html}</div></template>`
|
|
|
|
|
genPageDataCode(data.hoistedTags || [], pageData, replaceRegex).join(
|
|
|
|
|
'\n'
|
|
|
|
|
) +
|
|
|
|
|
`\n<template><div>${replaceConstants(
|
|
|
|
|
html,
|
|
|
|
|
replaceRegex,
|
|
|
|
|
vueTemplateBreaker
|
|
|
|
|
)}</div></template>`
|
|
|
|
|
|
|
|
|
|
debug(`[render] ${file} in ${Date.now() - start}ms.`)
|
|
|
|
|
|
|
|
|
@ -171,10 +155,42 @@ const scriptSetupRE = /<\s*script[^>]*\bsetup\b[^>]*/
|
|
|
|
|
const scriptClientRE = /<\s*script[^>]*\bclient\b[^>]*/
|
|
|
|
|
const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
|
|
|
|
|
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/
|
|
|
|
|
const jsStringBreaker = '\u200b'
|
|
|
|
|
const vueTemplateBreaker = '<wbr>'
|
|
|
|
|
|
|
|
|
|
function genReplaceRegexp(
|
|
|
|
|
userDefines: Record<string, any> = {},
|
|
|
|
|
isBuild: boolean
|
|
|
|
|
): RegExp {
|
|
|
|
|
// `process.env` need to be handled in both dev and build
|
|
|
|
|
// @see https://github.com/vitejs/vite/blob/cad27ee8c00bbd5aeeb2be9bfb3eb164c1b77885/packages/vite/src/node/plugins/clientInjections.ts#L57-L64
|
|
|
|
|
const replacements = ['process.env']
|
|
|
|
|
if (isBuild) {
|
|
|
|
|
replacements.push('import.meta', ...Object.keys(userDefines))
|
|
|
|
|
}
|
|
|
|
|
return new RegExp(
|
|
|
|
|
`\\b(${replacements
|
|
|
|
|
.map((key) => key.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'))
|
|
|
|
|
.join('|')})`,
|
|
|
|
|
'g'
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* To avoid env variables being replaced by vite:
|
|
|
|
|
* - insert `'\u200b'` char into those strings inside js string (page data)
|
|
|
|
|
* - insert `<wbr>` tag into those strings inside html string (vue template)
|
|
|
|
|
*
|
|
|
|
|
* @see https://vitejs.dev/guide/env-and-mode.html#production-replacement
|
|
|
|
|
*/
|
|
|
|
|
function replaceConstants(str: string, replaceRegex: RegExp, breaker: string) {
|
|
|
|
|
return str.replace(replaceRegex, (_) => `${_[0]}${breaker}${_.slice(1)}`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function genPageDataCode(tags: string[], data: PageData) {
|
|
|
|
|
function genPageDataCode(tags: string[], data: PageData, replaceRegex: RegExp) {
|
|
|
|
|
const dataJson = JSON.stringify(data)
|
|
|
|
|
const code = `\nexport const __pageData = JSON.parse(${JSON.stringify(
|
|
|
|
|
JSON.stringify(data)
|
|
|
|
|
replaceConstants(dataJson, replaceRegex, jsStringBreaker)
|
|
|
|
|
)})`
|
|
|
|
|
|
|
|
|
|
const existingScriptIndex = tags.findIndex((tag) => {
|
|
|
|
|