fix(analyze): use route summaries as the analyzer route index

Merged
WB
6d ago
+233-141

What?

The bundle analyzer now uses the route-summaries.json that Turbopack writes as its only route index. This covers next analyze, next build --analyze, next analyze export, the analyzer UI's route picker, and comparison views. routes.json is no longer written or read, and /_global-error is listed like any other route.

Why?

next analyze export failed with ENOENT on metadata routes that use generateImageMetadata or generateSitemaps, and the analyzer UI couldn't load their data either.

The cause was two route indexes that disagreed:

  • Turbopack writes each route's analyze.data under its structural entrypoint key, e.g. /icon or /sitemap.xml. It also lists those keys in route-summaries.json, along with each route's sizes.
  • routes.json was built separately from the routes manifest, which has the generator-adjusted pages /icon/[__metadata_id__] and /sitemap/[__metadata_id__].

Readers turn each listed route straight into <route>/analyze.data, so they asked for files that were never written.

Since route-summaries.json already has every route plus its sizes, a second index is redundant. Dropping it makes the route list and the data on disk agree by construction.

How?

  • Capture: both capture commands read and validate the summaries, then use that list for the snapshot's routeCount. Nothing is filtered, so /_global-error (which can be large) is now visible.
  • Export: next analyze export uses the same validated list, with the same --route filtering. If route-summaries.json is missing (some 16.4 canary snapshots predate it), the command fails with a clear message to re-run next analyze, without writing partial output.
  • UI:
    • A shared helper derives each build's route list from its own summaries, for the current build, the baseline, and the route picker.
    • The comparison strip counts routes from the summaries rather than the routeCount saved in older snapshot metadata, which didn't include /_global-error.

Compatibility: older snapshots that have route summaries keep working. Snapshots captured while this bug was present export and compare correctly without re-capturing, because their summaries already use the structural names. Their stale routes.json is ignored.

Tests

The test/e2e/next-analyze fixture now has a nested generateImageMetadata icon and a generateSitemaps sitemap. The suite checks, for both next analyze and next build --analyze, that:

  • the summary route set, including /_global-error, has analyze.data for every route;
  • exports emit exactly those routes;
  • routeCount matches the summaries;
  • routes.json is not written.

It also checks that a stale legacy routes.json is ignored, and that a snapshot without summaries fails with the re-capture message. I also exported a snapshot captured by the buggy published canary with the locally built CLI: it now exports /icon without re-capturing.

Fixes #99970