mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
d0798a0416
## 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>
15 lines
287 B
JavaScript
15 lines
287 B
JavaScript
import fs from 'fs/promises'
|
|
|
|
/** @type {import('next').NextAdapter} */
|
|
const adapter = {
|
|
name: 'test-adapter',
|
|
async onBuildComplete(ctx) {
|
|
await fs.writeFile(
|
|
new URL('build-complete.json', import.meta.url),
|
|
JSON.stringify(ctx)
|
|
)
|
|
},
|
|
}
|
|
|
|
export default adapter
|