fix: respect pageExtensions in prerender and exclude _ prefixed api files#591
fix: respect pageExtensions in prerender and exclude _ prefixed api files#591james-elicx merged 4 commits intomainfrom
Conversation
…iles - cli.ts: hoist resolveNextConfig so pageExtensions is passed to printBuildReport - run-prerender.ts: pass config.pageExtensions to pagesRouter/apiRouter (previously defaulted to ["tsx","ts","jsx","js"] regardless of next.config.js) - pages-router.ts (scanApiRoutes): add _ prefix exclude, matching pages/ behaviour - report.ts: tighten printBuildReport signature (pageExtensions required, not optional) - tests: add coverage for _ prefix exclusion in pages/api and pageExtensions filtering
commit: |
|
|
/bigbonk review |
There was a problem hiding this comment.
Review
Good bug fix — the pageExtensions plumbing was clearly broken in the prerender and build-report paths, and the _-prefix exclusion for API routes is a correct parity fix. The tests are well-structured with proper cleanup. One issue:
Bug: appRouter in run-prerender.ts still missing pageExtensions
The PR fixes pagesRouter/apiRouter calls in run-prerender.ts (lines 227-228) but the appRouter call on line 195 still reads:
const routes = await appRouter(appDir);This should be:
const routes = await appRouter(appDir, config.pageExtensions);Without this, the App Router prerender phase still scans with default extensions — the exact same class of bug this PR fixes for Pages Router. A project with pageExtensions: ["page.tsx", "page.ts"] in next.config.js would get phantom app routes during prerender.
Everything else looks correct
cli.ts: HoistingresolveNextConfigis clean — avoids the double-resolve and makes the config available toprintBuildReport. The diff is minimal and correct.report.ts: MakingpageExtensionsrequired (not optional) is the right call — forces callers to be explicit.pages-router.ts: The_-prefix exclude inscanApiRoutesis consistent with howscanPageRoutesalready handles it (line 76). Node.jsglob'sexcludecallback applies to both files and directory entries, so_helpers.ts(file) and_utils/(directory) are both correctly excluded.- Tests: Good coverage — the
build-report.test.tsadditions verify the end-to-endprintBuildReportpath with both routers and both include/exclude cases. Thepage-extensions-routing.test.tsaddition specifically tests the_-prefix exclusion. Proper cache invalidation and tmp cleanup throughout.
Minor: afterEach cleanup in build-report.test.ts only invalidates app route cache
In the printBuildReport respects pageExtensions describe block, afterEach calls invalidateAppRouteCache() but not invalidateRouteCache(pagesDir). The pages router tests do call invalidateRouteCache in their finally blocks, so this isn't a correctness issue in practice — but if a pages router test were to fail before reaching finally, the cache wouldn't be cleaned up by afterEach. Consider adding invalidateRouteCache for the pages dir in afterEach too for robustness.
Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>
|
Review posted successfully on PR #591. Here's a summary of the findings: Key issue found: Everything else is correct:
|
…cache cleanup - run-prerender.ts: appRouter(appDir) was missing config.pageExtensions, same class of bug as the pagesRouter/apiRouter fix — App Router prerender would scan with default extensions regardless of next.config.js - build-report.test.ts: afterEach now invalidates both app and pages route caches so a test failure can't leak cached routes into subsequent tests
Summary
run-prerender.ts:pagesRouter/apiRouterwere called withoutpageExtensions, so the prerender phase always scanned with default extensions (tsx,ts,jsx,js) regardless ofnext.config.js. Now passesconfig.pageExtensions.cli.ts: HoistedresolveNextConfigsonextConfig.pageExtensionsis forwarded toprintBuildReport(previously the result was discarded inline).pages-router.ts(scanApiRoutes): Added_-prefix exclude to match Next.js behaviour —pages/api/_helpers.tswas becoming a/api/_helpersroute.report.ts: TightenedprintBuildReportsignature —pageExtensionsis now required (not optional), making callers explicit.Testing
tests/page-extensions-routing.test.ts: verifies_-prefixed files inpages/api/are excluded.tests/build-report.test.ts(added in prior work): verifyprintBuildReportrespectspageExtensionsfor both App and Pages Router.Notes
With default
pageExtensions: ["tsx","ts","jsx","js"], a file likehome.spec.tsxinpages/will still become a route — same as Next.js itself. The correct user-side fix for colocation ispageExtensions: ["page.tsx"], which vinext now respects end-to-end.