wip: prod build for dynamic routes

pull/2005/head
Evan You 2 years ago
parent d6952f37b7
commit 80fb3b0e98

@ -9,6 +9,7 @@ import { bundle, okMark, failMark } from './bundle'
import { createRequire } from 'module'
import { pathToFileURL } from 'url'
import pkgDir from 'pkg-dir'
import { resolveRoutes } from '../plugins/dynamicRoutesPlugin'
export async function build(
root?: string,
@ -31,9 +32,16 @@ export async function build(
}
try {
const [dynamicRoutes] = await resolveRoutes(siteConfig.dynamicRoutes)
const allPages = [
...siteConfig.pages,
...dynamicRoutes.map((r) => r.path)
]
const { clientResult, serverResult, pageToHashMap } = await bundle(
siteConfig,
buildOptions
buildOptions,
allPages
)
const entryPath = path.join(siteConfig.tempDir, 'app.js')
@ -64,12 +72,10 @@ export async function build(
// as JS object literal.
const hashMapString = JSON.stringify(JSON.stringify(pageToHashMap))
const pages = ['404.md', ...siteConfig.pages].map(
(page) => siteConfig.rewrites.map[page] || page
)
await Promise.all(
pages.map((page) =>
['404.md', ...allPages]
.map((page) => siteConfig.rewrites.map[page] || page)
.map((page) =>
renderPage(
render,
siteConfig,

@ -20,7 +20,8 @@ export const failMark = '\x1b[31m✖\x1b[0m'
// bundles the VitePress app for both client AND server.
export async function bundle(
config: SiteConfig,
options: BuildOptions
options: BuildOptions,
allPages: string[]
): Promise<{
clientResult: RollupOutput
serverResult: RollupOutput
@ -34,7 +35,7 @@ export async function bundle(
// the loading is done via filename conversion rules so that the
// metadata doesn't need to be included in the main chunk.
const input: Record<string, string> = {}
config.pages.forEach((file) => {
allPages.forEach((file) => {
// page filename conversion
// foo/bar.md -> foo_bar.md
const alias = config.rewrites.map[file] || file

@ -197,9 +197,13 @@ function resolvePageImports(
page = config.rewrites.inv[page] || page
// find the page's js chunk and inject script tags for its imports so that
// they start fetching as early as possible
const srcPath = normalizePath(
fs.realpathSync(path.resolve(config.srcDir, page))
)
let srcPath = page
try {
srcPath = normalizePath(fs.realpathSync(path.resolve(config.srcDir, page)))
} catch (e) {
// if the page is a virtual page generated by a dynamic route this would
// fail, which is expected
}
const pageChunk = result.output.find(
(chunk) => chunk.type === 'chunk' && chunk.facadeModuleId === srcPath
) as OutputChunk

@ -9,7 +9,7 @@ import c from 'picocolors'
import path from 'path'
import type { SiteConfig } from '../config'
export const dynamicRouteRE = /\[(\.\.\.)?\w+\]/
export const dynamicRouteRE = /\[(\w+?)\]/g
interface UserRouteConfig {
params: Record<string, string>
@ -26,7 +26,7 @@ interface RouteModule {
dependencies: string[]
}
type ResolvedRouteConfig = UserRouteConfig & {
export type ResolvedRouteConfig = UserRouteConfig & {
/**
* the raw route, e.g. foo/[bar].md
*/
@ -81,6 +81,17 @@ export const dynamicRoutesPlugin = async (
})
},
resolveId(id) {
if (!id.endsWith('.md')) return
const normalizedId = id.startsWith(config.root)
? normalizePath(path.relative(config.root, id))
: id.replace(/^\//, '')
const matched = resolvedRoutes.find((r) => r.path === normalizedId)
if (matched) {
return normalizedId
}
},
load(id) {
const matched = resolvedRoutes.find((r) => r.path === id)
if (matched) {
@ -121,7 +132,7 @@ export const dynamicRoutesPlugin = async (
}
}
async function resolveRoutes(routes: string[]) {
export async function resolveRoutes(routes: string[]) {
const pendingResolveRoutes: Promise<ResolvedRouteConfig[]>[] = []
const routeFileToModulesMap: Record<string, string[]> = {}
@ -165,9 +176,10 @@ async function resolveRoutes(routes: string[]) {
const paths = await (typeof loader === 'function' ? loader() : loader)
return paths.map((userConfig) => {
return {
path:
'/' +
route.replace(/\[(\w+)\]/g, (_, key) => userConfig.params[key]),
path: route.replace(
dynamicRouteRE,
(_, key) => userConfig.params[key]
),
route,
...userConfig
}

Loading…
Cancel
Save