[pull] canary from vercel:canary - #1303
Merged
Merged
Conversation
## Summary ### Original issue Pages API functions produced through a build adapter can fail during function initialization, before the customer handler executes: ``` Cannot find module 'next/dist/compiled/next-server/pages-turbo.runtime.prod.js' ``` The failure is triggered when an externalized dependency used by the API route imports a Next.js module such as `next/head`. At runtime the load path is: ``` external dependency -> next/head -> head-manager-context.shared-runtime -> Pages vendored head-manager context -> pages/module.compiled.js -> pages[-turbo].runtime.prod.js ``` The two important edges at the end of this chain are selected dynamically. The Next.js require hook redirects the shared-runtime import to the Pages vendored context, and `pages/module.compiled.js` selects the bundler-specific production renderer. As a result, a Pages API entry trace does not discover the regular Pages renderer. It naturally contains `pages-api[-turbo].runtime.prod.js`, which is the runtime for the API route module, but not `pages[-turbo].runtime.prod.js`, which is reached through the external `next/head` import. This is why the failure is specific to Pages API routes. A regular Pages SSR entry already references and traces the Pages renderer. App Router entries use different route modules and traces. ### Fix Trace the hidden Pages renderer dependency using the mechanism appropriate to each bundler: - **Turbopack:** add `pages-turbo.runtime.prod.js` as an explicit entry in `Project::pages_traced_modules`. The existing native Turbopack module graph then traces its full runtime closure. This does not run Node File Trace and remains scoped to Pages endpoints. - **Webpack:** run the existing Node File Trace path on `pages.runtime.prod.js` and merge that closure into the Pages shared assets. This code remains inside the non-Turbopack branch. The existing require-hook modules remain separate, and App Router or neutral endpoint trace sets are unchanged. No adapter change is required. ### Regression test The fixture externalizes a package that imports `next/head`, matching the reported dependency boundary. The test builds with an adapter, materializes only the generated Pages API function entry and its provided assets into a clean directory, initializes the production environment, and requires the handler in a child process. This verifies the observable initialization behavior under both Turbopack and Webpack rather than asserting a particular output file list. ## Verification - `cargo check -p next-api` - `pnpm --filter=next build` - `pnpm test-start-turbo test/production/adapter-pages-api-runtime/adapter-pages-api-runtime.test.ts` - `pnpm test-start-webpack test/production/adapter-pages-api-runtime/adapter-pages-api-runtime.test.ts` <!-- NEXT_JS_LLM --> Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
The `use-cache-private` suite covered private caches in server components only, so this adds a route handler that calls one `'use cache: private'` function three times: a concurrent pair, and a third call after a short delay. The concurrent pair joins a single in-flight invocation, while the delayed call lands after the map of pending intra-request invocations has dropped its entry, so it is served from the completed entry that the request retains. Each call passes a fresh object literal, which makes the React `cache()` memo miss on reference equality so that the lookup falls through to the serialized cache key. The cache function also reads a cookie, which covers that request APIs are allowed inside a private cache in a route handler. A second test asserts that nothing is shared across requests. In production private entries are neither persisted nor deduped across requests, so every request re-runs the cache function. In development they are persisted and forced to `revalidate: 0`, so the next request is served the stale entry while a fresh one warms in the background, which the dev branch of the test follows. Both tests pass their own `id` search param, and therefore use their own cache key, so the entry that dev persists for one is never served to the other. This also drops the claim that the directive is not available in route handlers from the `'use cache: private'` reference. Nothing in the source rejects it, and it was already allowed for request work unit stores when that note was written.
…97350) Adopts #97150. Closes #97150. Fixes #96859 ### What? Since 16.3.0, builds fail for pages-router files named `sitemap` or `robots` that export `getStaticProps`/`getServerSideProps`: ``` Error: "getStaticProps" is not supported in app/. ``` This is a regression from #94962, which added the metadata conventions (`sitemap`, `robots`, `manifest`, `icon`, …) to the app-entry filename regex in `ReactServerComponentValidator::assert_invalid_api`. The regex only looks at the filename, so a file like `pages/sitemap.js` is now mistaken for an app entry and rejected for exporting `getStaticProps`. ### How? A file is only treated as an app entry when it's inside `appDir`, reusing the gate `assert_server_filename` already applies to `error.js`. The pages compilation context has no `appDir`, so pages-router files are never validated as app entries. On the test side: - The fixtures that exercise the app-entry checks moved under `app-dir/`, since the test harness derives `appDir` from the fixture path. Their contents are unchanged. - A new fixture (plus a `sitemap.js` fixture glob) asserts that a pages-style `sitemap.js` compiles without errors. - A new e2e suite, `test/e2e/pages-metadata-filenames`, covers `pages/sitemap.js` with `getStaticProps` and `pages/robots.js` with `getServerSideProps`. It fails without the fix under Turbopack (build and dev) and passes with it under both Turbopack and webpack. Supersedes #96873 (same approach, closed by its author) and closes #96967. --------- Co-authored-by: Rodrigo Arias <rodrigo@arias.me>
## Summary - trace the primary App Router and Pages Router route-module load inside `loadComponents` - expose `LoadComponents.loadRouteModule` as the default `load route module` OpenTelemetry span - verify the span in development and production with both Turbopack and Webpack ## Why Route-module evaluation can account for cold request time before route preparation and rendering begin. Keeping this boundary in the Next.js server makes it available to `next dev`, self-hosted `next start`, direct entrypoints, and deployment integrations without depending on an adapter-specific launcher. The span wraps only the requested route module. It does not include `_app`, `_document`, rendering, or any adapter launcher work, and it does not add filesystem paths, raw URLs, or other high-cardinality attributes. ## Verification - `pnpm build-all` - `pnpm --filter=next build` - `pnpm --filter=next types` - `pnpm exec jest packages/next/src/server/lib/trace/tracer.test.ts --runInBand` - focused OpenTelemetry E2E in `test-dev-turbo`, `test-dev-webpack`, `test-start-turbo`, and `test-start-webpack` - Prettier, ESLint, and `git diff --check`
## Summary - trace the full route-module preparation boundary as `RouteModule.prepare` - record manifest loading as one aggregate `RouteModule.loadManifests` child span - keep route preparation visible by default while exposing manifest detail only with verbose tracing - cover normal and direct-entrypoint server lifecycles without relying on test ordering ## Why Route preparation is the stable boundary between loading a route module and executing it. The parent span shows the total setup cost; the aggregate manifest child explains manifest work without creating per-file spans or exposing paths. ## Verification - `pnpm build-all` - `pnpm --filter=next build` - `pnpm --filter=next types` - `pnpm exec jest packages/next/src/server/lib/trace/tracer.test.ts --runInBand` - focused OpenTelemetry E2E in development and production with Turbopack and Webpack - Request Insights route-preparation E2E with Turbopack and Webpack - Prettier, ESLint, and `git diff --check` ## Stack Depends on **Trace route module loading**.
## Summary - trace instrumentation module loading and `register()` execution as separate startup spans - preserve the original timestamps when the OpenTelemetry provider is installed by `register()` itself - export both lifecycle spans by default without attaching them to an unrelated request - verify standard and direct-entrypoint startup with a collector connected before the server starts ## Why Loading `instrumentation.ts` and running the user-defined `register()` hook have different owners and remediation paths. Separate spans make startup delays attributable while preserving honest lifecycle parentage: these spans normally occur before a request identity exists. ## Verification - `pnpm build-all` - `pnpm --filter=next build` - `pnpm --filter=next types` - `pnpm exec jest packages/next/src/server/lib/trace/tracer.test.ts --runInBand` - focused instrumentation-startup E2E in development and production with Turbopack and Webpack - Prettier, ESLint, and `git diff --check` ## Stack Depends on **Trace route module preparation**.
…rs (#96898) Reverts #95739 It's fixed in the adapter: nextjs/adapter-vercel#81
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )