From c73fdfd87cbd5a2e57039ede6c545c67b2e43667 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 26 Jul 2023 17:08:53 -0700 Subject: [PATCH] Fix file tracing issues for not-found pages (#53231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the `.nft.json` output for not-found pages to correctly grab the client reference manifest. We were checking for `entryPoint.name.startsWith('app/')` but then asserting on `entryPoint.name === '/_not-found'` when determining the manifest path. This also fixes the build output to mark pages with `λ` if the corresponding page has dynamic data. This revealed a separate issue that de-opts all pages into dynamic rendering if the root `NotFound` page bails, tracked in [NEXT-1474](https://linear.app/vercel/issue/NEXT-1474/if-the-root-notfound-page-opts-into-dynamic-rendering-all-pages-do-too) [slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1683763412272429) --- packages/next/src/build/index.ts | 10 ++++++++++ .../plugins/next-trace-entrypoints-plugin.ts | 4 ++-- packages/next/src/server/base-server.ts | 3 +-- test/e2e/app-dir/not-found/not-found.test.ts | 16 +++++++++++++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index c71e2725dc8bd..b2dcb975f974a 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -2549,6 +2549,16 @@ export default async function build( appConfig.revalidate === 0 || exportConfig.initialPageRevalidationMap[page] === 0 + if (hasDynamicData && pageInfos.get(page)?.static) { + // if the page was marked as being static, but it contains dynamic data + // (ie, in the case of a static generation bailout), then it should be marked dynamic + pageInfos.set(page, { + ...(pageInfos.get(page) as PageInfo), + static: false, + isSsg: false, + }) + } + const isRouteHandler = isAppRouteRoute(originalAppPath) routes.forEach((route) => { diff --git a/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts b/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts index 7c4a7a72205c7..2be64402d3205 100644 --- a/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts +++ b/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts @@ -292,8 +292,8 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { // include the client reference manifest const clientManifestsForPage = entrypoint.name.endsWith('/page') || - entrypoint.name === '/not-found' || - entrypoint.name === '/_not-found' + entrypoint.name === 'app/not-found' || + entrypoint.name === 'app/_not-found' ? nodePath.join( outputPath, '..', diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 70660e4c5eca9..940c70c60bd48 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2640,8 +2640,7 @@ export default abstract class Server { let using404Page = false if (is404) { - // Rendering app routes only in render worker to make sure the require-hook is setup - if (this.hasAppDir && this.isRenderWorker) { + if (this.hasAppDir) { // Use the not-found entry in app directory result = await this.findPageComponents({ pathname: this.renderOpts.dev ? '/not-found' : '/_not-found', diff --git a/test/e2e/app-dir/not-found/not-found.test.ts b/test/e2e/app-dir/not-found/not-found.test.ts index c8fdf77f42206..e724553d25a5e 100644 --- a/test/e2e/app-dir/not-found/not-found.test.ts +++ b/test/e2e/app-dir/not-found/not-found.test.ts @@ -7,7 +7,21 @@ createNextDescribe( files: __dirname, skipDeployment: true, }, - ({ next, isNextDev }) => { + ({ next, isNextDev, isNextStart }) => { + if (isNextStart) { + it('should include not found client reference manifest in the file trace', async () => { + const fileTrace = JSON.parse( + await next.readFile('.next/server/app/_not-found.js.nft.json') + ) + + const isTraced = fileTrace.files.some((filePath) => + filePath.includes('_not-found_client-reference-manifest.js') + ) + + expect(isTraced).toBe(true) + }) + } + const runTests = ({ isEdge }: { isEdge: boolean }) => { it('should use the not-found page for non-matching routes', async () => { const browser = await next.browser('/random-content')