next.js
c420af22 - Turbopack: fix edge route handlers when cacheHandlers is configured (#100046)

Commit
25 days ago
Turbopack: fix edge route handlers when cacheHandlers is configured (#100046) ### What? Fixes Turbopack production and dev builds of App Router route handlers with `export const runtime = 'edge'` when `cacheHandlers` is configured. These builds currently fail with `edge-app-route.js: Expected ';', '}' or <eof>`. Webpack builds of the same app already work. ### Why? The webpack loader and Turbopack both fill the `edgeCacheHandlersRegistration` injection point in the shared `edge-app-route.ts` template, which sits at statement position after `const edgeCacheHandlers = {}`. - **webpack** emits assignment statements. - **Turbopack** (`wrap_edge_route` in `crates/next-core/src/next_app/app_route_entry.rs`) emitted object-literal property fragments, which don't parse at statement position. Existing coverage missed this because the edge fixture in `cache-handlers-upstream-wiring` only sets the singular `cacheHandler`. The loop that generates these entries never ran for an edge route. ### How? - **Turbopack codegen:** Turbopack now emits one assignment per configured kind (`edgeCacheHandlers[<kind>] = cacheHandlerN`), matching the webpack loader. Each kind is still serialized with `serde_json`. The template and the webpack loader are unchanged, so both bundlers keep sharing the same template contract. - **Regression fixture:** the new `edge-with-cache-handlers` fixture has two distinct handler modules (`default` and `custom`), one force-dynamic edge route and no edge page. It pins `cacheComponents: false` and `experimental.cachedNavigations: false`, because Cache Components is not supported on the edge runtime. Without both pins, the experimental CI shards would turn these flags on through env defaults, and the fixture would fail config validation or the build. - **What the test checks:** the route reads the cache-handler registry that `EdgeRouteModuleWrapper` fills before invoking it, and returns each handler's marker. The test asserts both markers over HTTP, so it fails if the build breaks or if either kind is missing or swapped. - The suite has no gates. The fixture is a valid edge app in every shard, so the assertions run everywhere, including deploy. - **Limits:** the test proves registration only. It doesn't exercise `'use cache'` hits or revalidation on edge. ### Verification | Run | Result | |---|---| | New test, `test-start-turbo`, unfixed published binary | ❌ fails with the parse error above, as expected | | New test, `test-start-turbo`, local native build with the fix | ✅ passes | | Existing edge test (`cacheComponents disabled, edge app router`), same fixed build | ✅ passes | | New test, `test-start-webpack` | ✅ passes | | New test, `test-dev-turbo` | ✅ passes | | New test with the experimental (cache-components) CI env, `test-start-turbo` and `test-dev-turbo` | ✅ passes | | Standalone repro (published canary.8 + fixed native binary), `next build` + `next start`, `GET` the edge route | ✅ builds and returns the expected JSON | Not run locally: deploy-mode tests (they run in CI). Fixes #99894 <!-- NEXT_JS_LLM --> <!-- fleet 826df9e4-b701-4396-9634-0b96a03345e7 --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Author
Parents
Loading