diff --git a/src/node/build/render.ts b/src/node/build/render.ts index 07d78bff..4b7dbd74 100644 --- a/src/node/build/render.ts +++ b/src/node/build/render.ts @@ -197,13 +197,14 @@ 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 - let srcPath = page + let srcPath = path.resolve(config.srcDir, page) try { - srcPath = normalizePath(fs.realpathSync(path.resolve(config.srcDir, page))) + srcPath = fs.realpathSync(srcPath) } catch (e) { // if the page is a virtual page generated by a dynamic route this would // fail, which is expected } + srcPath = normalizePath(srcPath) const pageChunk = result.output.find( (chunk) => chunk.type === 'chunk' && chunk.facadeModuleId === srcPath ) as OutputChunk diff --git a/src/node/config.ts b/src/node/config.ts index 25b93061..65dd2340 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -435,7 +435,7 @@ export async function resolvePages(srcDir: string, userConfig: UserConfig) { const dynamicRouteFiles = allMarkdownFiles.filter((p) => dynamicRouteRE.test(p) ) - const dynamicRoutes = await resolveDynamicRoutes(dynamicRouteFiles) + const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles) pages.push(...dynamicRoutes.routes.map((r) => r.path)) const rewrites = resolveRewrites(pages, userConfig.rewrites) diff --git a/src/node/plugins/dynamicRoutesPlugin.ts b/src/node/plugins/dynamicRoutesPlugin.ts index 6d0af4ac..435d5ab0 100644 --- a/src/node/plugins/dynamicRoutesPlugin.ts +++ b/src/node/plugins/dynamicRoutesPlugin.ts @@ -28,13 +28,17 @@ interface RouteModule { export type ResolvedRouteConfig = UserRouteConfig & { /** - * the raw route, e.g. foo/[bar].md + * the raw route (relative to src root), e.g. foo/[bar].md */ route: string /** - * the actual path with params resolved, e.g. foo/1.md + * the actual path with params resolved (relative to src root), e.g. foo/1.md */ path: string + /** + * absolute fs path + */ + fullPath: string } export const dynamicRoutesPlugin = async ( @@ -52,10 +56,10 @@ 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(/^\//, '') + ? id + : normalizePath(path.resolve(config.srcDir, id.replace(/^\//, ''))) const matched = config.dynamicRoutes.routes.find( - (r) => r.path === normalizedId + (r) => r.fullPath === normalizedId ) if (matched) { return normalizedId @@ -63,10 +67,10 @@ export const dynamicRoutesPlugin = async ( }, load(id) { - const matched = config.dynamicRoutes.routes.find((r) => r.path === id) + const matched = config.dynamicRoutes.routes.find((r) => r.fullPath === id) if (matched) { const { route, params, content } = matched - const routeFile = normalizePath(path.resolve(config.root, route)) + const routeFile = normalizePath(path.resolve(config.srcDir, route)) config.dynamicRoutes.fileToModulesMap[routeFile].add(id) let baseContent = fs.readFileSync(routeFile, 'utf-8') @@ -106,6 +110,7 @@ export const dynamicRoutesPlugin = async ( } export async function resolveDynamicRoutes( + srcDir: string, routes: string[] ): Promise { const pendingResolveRoutes: Promise[] = [] @@ -113,10 +118,11 @@ export async function resolveDynamicRoutes( for (const route of routes) { // locate corresponding route paths file - const jsPathsFile = route.replace(/\.md$/, '.paths.js') + const fullPath = path.resolve(srcDir, route) + const jsPathsFile = fullPath.replace(/\.md$/, '.paths.js') let pathsFile = jsPathsFile if (!fs.existsSync(jsPathsFile)) { - pathsFile = route.replace(/\.md$/, '.paths.ts') + pathsFile = fullPath.replace(/\.md$/, '.paths.ts') if (!fs.existsSync(pathsFile)) { console.warn( c.yellow( @@ -131,10 +137,7 @@ export async function resolveDynamicRoutes( // load the paths loader module let mod: RouteModule try { - mod = (await loadConfigFromFile( - {} as any, - path.resolve(pathsFile) - )) as RouteModule + mod = (await loadConfigFromFile({} as any, pathsFile)) as RouteModule } catch (e) { console.warn(`invalid paths file export in ${pathsFile}.`) continue @@ -143,12 +146,13 @@ export async function resolveDynamicRoutes( if (mod) { // this array represents the virtual modules affected by this route const matchedModuleIds = (routeFileToModulesMap[ - normalizePath(path.resolve(route)) + normalizePath(path.resolve(srcDir, route)) ] = new Set()) // each dependency (including the loader module itself) also point to the // same array for (const dep of mod.dependencies) { + // deps are resolved relative to cwd routeFileToModulesMap[normalizePath(path.resolve(dep))] = matchedModuleIds } @@ -157,11 +161,13 @@ export async function resolveDynamicRoutes( const loader = mod.config.paths const paths = await (typeof loader === 'function' ? loader() : loader) return paths.map((userConfig) => { + const resolvedPath = route.replace( + dynamicRouteRE, + (_, key) => userConfig.params[key] + ) return { - path: route.replace( - dynamicRouteRE, - (_, key) => userConfig.params[key] - ), + path: resolvedPath, + fullPath: normalizePath(path.resolve(srcDir, resolvedPath)), route, ...userConfig }