Handle callGetStaticPaths TODO (#7558)

This commit is contained in:
Bjorn Lu 2023-07-04 21:58:41 +08:00 committed by GitHub
parent c412e4a7bb
commit 917f25cffe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 37 deletions

View file

@ -305,32 +305,27 @@ async function getPathsForRoute(
builtPaths.add(pageData.route.pathname);
} else {
const route = pageData.route;
const result = await callGetStaticPaths({
const staticPaths = await callGetStaticPaths({
mod,
route: pageData.route,
route,
routeCache: opts.routeCache,
isValidate: false,
logging: opts.logging,
ssr: isServerLikeOutput(opts.settings.config),
})
.then((_result) => {
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';
debug(
'build',
`├── ${colors.bold(colors.green('✔'))} ${route.component}${colors.magenta(
`[${_result.staticPaths.length} ${label}]`
)}`
);
return _result;
})
.catch((err) => {
debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
throw err;
});
}).catch((err) => {
debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
throw err;
});
// Save the route cache so it doesn't get called again
opts.routeCache.set(route, result);
const label = staticPaths.length === 1 ? 'page' : 'pages';
debug(
'build',
`├── ${colors.bold(colors.green('✔'))} ${route.component}${colors.magenta(
`[${staticPaths.length} ${label}]`
)}`
);
paths = result.staticPaths
paths = staticPaths
.map((staticPath) => {
try {
return route.generate(staticPath.params);

View file

@ -27,17 +27,18 @@ export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise
validatePrerenderEndpointCollision(route, mod, params);
let routeCacheEntry = routeCache.get(route);
// During build, the route cache should already be populated.
// During development, the route cache is filled on-demand and may be empty.
// TODO(fks): Can we refactor getParamsAndProps() to receive routeCacheEntry
// as a prop, and not do a live lookup/populate inside this lower function call.
if (!routeCacheEntry) {
routeCacheEntry = await callGetStaticPaths({ mod, route, isValidate: true, logging, ssr });
routeCache.set(route, routeCacheEntry);
}
const staticPaths = await callGetStaticPaths({
mod,
route,
routeCache,
isValidate: true,
logging,
ssr,
});
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, params, route);
const matchedStaticPath = findPathItemByKey(staticPaths, params, route);
if (!matchedStaticPath && (ssr ? route.prerender : true)) {
throw new AstroError({
...AstroErrorData.NoMatchingStaticPathFound,

View file

@ -17,23 +17,32 @@ import { generatePaginateFunction } from './paginate.js';
interface CallGetStaticPathsOptions {
mod: ComponentInstance;
route: RouteData;
routeCache: RouteCache;
isValidate: boolean;
logging: LogOptions;
ssr: boolean;
}
export async function callGetStaticPaths({
isValidate,
logging,
mod,
route,
routeCache,
isValidate,
logging,
ssr,
}: CallGetStaticPathsOptions): Promise<RouteCacheEntry> {
}: CallGetStaticPathsOptions): Promise<GetStaticPathsResultKeyed> {
const cached = routeCache.get(route);
if (cached?.staticPaths) return cached.staticPaths;
validateDynamicRouteModule(mod, { ssr, logging, route });
// No static paths in SSR mode. Return an empty RouteCacheEntry.
if (ssr && !route.prerender) {
return { staticPaths: Object.assign([], { keyed: new Map() }) };
const entry: GetStaticPathsResultKeyed = Object.assign([], { keyed: new Map() });
routeCache.set(route, { ...cached, staticPaths: entry });
return entry;
}
// Add a check here to make TypeScript happy.
// This is already checked in validateDynamicRouteModule().
if (!mod.getStaticPaths) {
@ -66,12 +75,11 @@ export async function callGetStaticPaths({
keyedStaticPaths.keyed.set(paramsKey, sp);
}
return {
staticPaths: keyedStaticPaths,
};
routeCache.set(route, { ...cached, staticPaths: keyedStaticPaths });
return keyedStaticPaths;
}
export interface RouteCacheEntry {
interface RouteCacheEntry {
staticPaths: GetStaticPathsResultKeyed;
}
@ -99,7 +107,7 @@ export class RouteCache {
// NOTE: This shouldn't be called on an already-cached component.
// Warn here so that an unexpected double-call of getStaticPaths()
// isn't invisible and developer can track down the issue.
if (this.mode === 'production' && this.cache[route.component]) {
if (this.mode === 'production' && this.cache[route.component]?.staticPaths) {
warn(
this.logging,
'routeCache',