feat: dynamic routes

This commit completes the feature by adding HMR for dependencies of
path loader files.

Based on previous commits:
2582058, dea831f, 99693c6, c70ab70, bc99e5d
pull/2005/head
Evan You 2 years ago
parent 5913ebc34f
commit 24fa862c39

@ -185,7 +185,7 @@ export interface SiteConfig<ThemeConfig = any>
pages: string[] pages: string[]
dynamicRoutes: { dynamicRoutes: {
routes: ResolvedRouteConfig[] routes: ResolvedRouteConfig[]
fileToModulesMap: Record<string, string[]> fileToModulesMap: Record<string, Set<string>>
} }
rewrites: { rewrites: {
map: Record<string, string | undefined> map: Record<string, string | undefined>

@ -67,7 +67,7 @@ export const dynamicRoutesPlugin = async (
if (matched) { if (matched) {
const { route, params, content } = matched const { route, params, content } = matched
const routeFile = normalizePath(path.resolve(config.root, route)) const routeFile = normalizePath(path.resolve(config.root, route))
config.dynamicRoutes.fileToModulesMap[routeFile].push(id) config.dynamicRoutes.fileToModulesMap[routeFile].add(id)
let baseContent = fs.readFileSync(routeFile, 'utf-8') let baseContent = fs.readFileSync(routeFile, 'utf-8')
@ -90,9 +90,12 @@ export const dynamicRoutesPlugin = async (
async handleHotUpdate(ctx) { async handleHotUpdate(ctx) {
const mods = config.dynamicRoutes.fileToModulesMap[ctx.file] const mods = config.dynamicRoutes.fileToModulesMap[ctx.file]
if (mods) { if (mods) {
// path loader module updated, reset loaded routes // path loader module or deps updated, reset loaded routes
if (/\.paths\.[jt]s$/.test(ctx.file)) { if (!/\.md$/.test(ctx.file)) {
await resolvePages(config.srcDir, config.userConfig) Object.assign(
config,
await resolvePages(config.srcDir, config.userConfig)
)
} }
for (const id of mods) { for (const id of mods) {
ctx.modules.push(server.moduleGraph.getModuleById(id)!) ctx.modules.push(server.moduleGraph.getModuleById(id)!)
@ -106,7 +109,7 @@ export async function resolveDynamicRoutes(
routes: string[] routes: string[]
): Promise<SiteConfig['dynamicRoutes']> { ): Promise<SiteConfig['dynamicRoutes']> {
const pendingResolveRoutes: Promise<ResolvedRouteConfig[]>[] = [] const pendingResolveRoutes: Promise<ResolvedRouteConfig[]>[] = []
const routeFileToModulesMap: Record<string, string[]> = {} const routeFileToModulesMap: Record<string, Set<string>> = {}
for (const route of routes) { for (const route of routes) {
// locate corresponding route paths file // locate corresponding route paths file
@ -138,10 +141,17 @@ export async function resolveDynamicRoutes(
} }
if (mod) { if (mod) {
// route md file and route paths loader file point to the same array // this array represents the virtual modules affected by this route
routeFileToModulesMap[mod.path] = routeFileToModulesMap[ const matchedModuleIds = (routeFileToModulesMap[
path.resolve(route) normalizePath(path.resolve(route))
] = [] ] = new Set())
// each dependency (including the loader module itself) also point to the
// same array
for (const dep of mod.dependencies) {
routeFileToModulesMap[normalizePath(path.resolve(dep))] =
matchedModuleIds
}
const resolveRoute = async (): Promise<ResolvedRouteConfig[]> => { const resolveRoute = async (): Promise<ResolvedRouteConfig[]> => {
const loader = mod.config.paths const loader = mod.config.paths

@ -71,7 +71,7 @@ export const staticDataPlugin: Plugin = {
const res = await loadConfigFromFile({} as any, id) const res = await loadConfigFromFile({} as any, id)
// record deps for hmr // record deps for hmr
if (res) { if (server && res) {
for (const dep of res.dependencies) { for (const dep of res.dependencies) {
depToLoaderModuleIdMap[normalizePath(path.resolve(dep))] = id depToLoaderModuleIdMap[normalizePath(path.resolve(dep))] = id
} }
@ -121,7 +121,7 @@ export const staticDataPlugin: Plugin = {
}, },
handleHotUpdate(ctx) { handleHotUpdate(ctx) {
const file = normalizePath(ctx.file) const file = ctx.file
// dependency of data loader changed // dependency of data loader changed
// (note the dep array includes the loader file itself) // (note the dep array includes the loader file itself)

Loading…
Cancel
Save