[next]: normalize source path for special app-dir metadata files (#11579)

When specifying a functions configuration in `vercel.json`, we attempt to find source files for all entrypoints.  This attempts to normalize those source paths for some special cases so that we don't show a build warning for completely normal usage.

- `/_not-found` is an entrypoint automatically inserted by Next.js -- if we don't find a source file for it, don't warn, as the user might not have added one
- special metadata files like `favicon.ico` and `opengraph-image.<ext>` will be bundled as `favicon.ico/route.js` but the source file will be the raw extension.
This commit is contained in:
Zack Tanner
2024-05-13 09:04:16 -07:00
committed by GitHub
parent c224fb1d2e
commit 67afc26085
13 changed files with 91 additions and 7 deletions

View File

@@ -1439,6 +1439,13 @@ async function getSourceFilePathFromPage({
}
}
// if we got here, and didn't find a source not-found file, then it was the one injected
// by Next.js. There's no need to warn or return a source file in this case, as it won't have
// any configuration applied to it.
if (page === '/_not-found/page') {
return '';
}
console.log(
`WARNING: Unable to find source file for page ${page} with extensions: ${extensionsToTry.join(
', '
@@ -1565,15 +1572,13 @@ export async function getPageLambdaGroups({
}
if (config && config.functions) {
// `pages` are normalized without route groups (e.g., /app/(group)/page.js).
// we keep track of that mapping in `inversedAppPathManifest`
// `getSourceFilePathFromPage` needs to use the path from source to properly match the config
const pageFromManifest = inversedAppPathManifest?.[routeName];
const sourceFile = await getSourceFilePathFromPage({
workPath: entryPath,
// since this function is used by both `pages` and `app`, the manifest might not be provided
// so fallback to normal behavior of just checking the `page`.
page: pageFromManifest ?? page,
page: normalizeSourceFilePageFromManifest(
routeName,
page,
inversedAppPathManifest
),
pageExtensions,
});
@@ -1657,6 +1662,43 @@ export async function getPageLambdaGroups({
return groups;
}
// `pages` are normalized without route groups (e.g., /app/(group)/page.js).
// we keep track of that mapping in `inversedAppPathManifest`
// `getSourceFilePathFromPage` needs to use the path from source to properly match the config
function normalizeSourceFilePageFromManifest(
routeName: string,
page: string,
inversedAppPathManifest?: Record<string, string>
) {
const pageFromManifest = inversedAppPathManifest?.[routeName];
if (!pageFromManifest) {
// since this function is used by both `pages` and `app`, the manifest might not be provided
// so fallback to normal behavior of just checking the `page`.
return page;
}
const metadataConventions = [
'/favicon.',
'/icon.',
'/apple-icon.',
'/opengraph-image.',
'/twitter-image.',
'/sitemap.',
'/robots.',
];
// these special metadata files for will not contain `/route` or `/page` suffix, so return the routeName as-is.
const isSpecialFile = metadataConventions.some(convention =>
routeName.startsWith(convention)
);
if (isSpecialFile) {
return routeName;
}
return pageFromManifest;
}
export const outputFunctionFileSizeInfo = (
pages: string[],
pseudoLayer: PseudoLayer,