From e78eee25c518dcad08500e17555146fe154dba09 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Fri, 29 Sep 2023 15:11:45 -0700 Subject: [PATCH] Add additional handling for experimental-compile (#56224) This ensures we properly set the `isReady` flag when building with `experimental-compile` and enables our main app dir test suite to ensure we don't regress on it. --- packages/next-plugin-storybook/package.json | 3 - packages/next/src/server/base-server.ts | 4 + packages/next/src/server/next.ts | 39 ++++- packages/next/src/server/render.tsx | 7 +- packages/next/src/shared/lib/router/router.ts | 1 + packages/next/src/shared/lib/utils.ts | 1 + pnpm-lock.yaml | 138 +----------------- .../app-dir/app/experimental-compile.test.ts | 9 ++ test/e2e/app-dir/app/index.test.ts | 15 +- 9 files changed, 64 insertions(+), 153 deletions(-) create mode 100644 test/e2e/app-dir/app/experimental-compile.test.ts diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 44c124abb0..85664b989b 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -4,8 +4,5 @@ "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" - }, - "peerDependencies": { - "next": "*" } } diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 0021ff6cf8..19ca288357 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2290,6 +2290,10 @@ export default abstract class Server { const isPageIncludedInStaticPaths = staticPathKey && staticPaths?.includes(staticPathKey) + if ((this.nextConfig.experimental as any).isExperimentalCompile) { + fallbackMode = 'blocking' + } + // When we did not respond from cache, we need to choose to block on // rendering or return a skeleton. // diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index 20d514929e..fd987b9c8b 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -13,9 +13,12 @@ import './node-polyfill-crypto' import { default as Server } from './next-server' import * as log from '../build/output/log' import loadConfig from './config' -import { resolve } from 'path' +import path, { resolve } from 'path' import { NON_STANDARD_NODE_ENV } from '../lib/constants' -import { PHASE_DEVELOPMENT_SERVER } from '../shared/lib/constants' +import { + PHASE_DEVELOPMENT_SERVER, + SERVER_FILES_MANIFEST, +} from '../shared/lib/constants' import { PHASE_PRODUCTION_SERVER } from '../shared/lib/constants' import { getTracer } from './lib/trace/tracer' import { NextServerSpan } from './lib/trace/constants' @@ -163,17 +166,39 @@ export class NextServer { } private async [SYMBOL_LOAD_CONFIG]() { - return ( + const dir = resolve(this.options.dir || '.') + + const config = this.options.preloadedConfig || - loadConfig( + (await loadConfig( this.options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER, - resolve(this.options.dir || '.'), + dir, { customConfig: this.options.conf, silent: true, } - ) - ) + )) + + // check serialized build config when available + if (process.env.NODE_ENV === 'production') { + try { + const serializedConfig = require(path.join( + dir, + '.next', + SERVER_FILES_MANIFEST + )).config + + // @ts-expect-error internal field + config.experimental.isExperimentalConfig = + serializedConfig.experimental.isExperimentalCompile + } catch (_) { + // if distDir is customized we don't know until we + // load the config so fallback to loading the config + // from next.config.js + } + } + + return config } private async getServer() { diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx index 7a67f4d40d..1adfa8157f 100644 --- a/packages/next/src/server/render.tsx +++ b/packages/next/src/server/render.tsx @@ -495,7 +495,7 @@ export async function renderToHTMLImpl( ) } - const isAutoExport = + let isAutoExport = !hasPageGetInitialProps && defaultAppGetInitialProps && !isSSG && @@ -511,6 +511,7 @@ export async function renderToHTMLImpl( private: false, stateful: false, }) + isAutoExport = false } if (hasPageGetInitialProps && isSSG) { @@ -638,7 +639,8 @@ export async function renderToHTMLImpl( const routerIsReady = !!( getServerSideProps || hasPageGetInitialProps || - (!defaultAppGetInitialProps && !isSSG) + (!defaultAppGetInitialProps && !isSSG) || + isExperimentalCompile ) const router = new ServerRouter( pathname, @@ -1443,6 +1445,7 @@ export async function renderToHTMLImpl( nextExport: nextExport === true ? true : undefined, // If this is a page exported by `next export` autoExport: isAutoExport === true ? true : undefined, // If this is an auto exported page isFallback, + isExperimentalCompile, dynamicIds: dynamicImportsIds.size === 0 ? undefined diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index 940d608676..db0642e136 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -830,6 +830,7 @@ export default class Router implements BaseRouter { this.isReady = !!( self.__NEXT_DATA__.gssp || self.__NEXT_DATA__.gip || + self.__NEXT_DATA__.isExperimentalCompile || (self.__NEXT_DATA__.appGip && !self.__NEXT_DATA__.gsp) || (!autoExportDynamic && !self.location.search && diff --git a/packages/next/src/shared/lib/utils.ts b/packages/next/src/shared/lib/utils.ts index 4e8036a689..771f11b4be 100644 --- a/packages/next/src/shared/lib/utils.ts +++ b/packages/next/src/shared/lib/utils.ts @@ -94,6 +94,7 @@ export type NEXT_DATA = { nextExport?: boolean autoExport?: boolean isFallback?: boolean + isExperimentalCompile?: boolean dynamicIds?: (string | number)[] err?: Error & { statusCode?: number diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fcfc06be91..9171306433 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1482,11 +1482,7 @@ importers: specifier: ^0.7.0 version: 0.7.3 - packages/next-plugin-storybook: - dependencies: - next: - specifier: '*' - version: 13.5.3(@babel/core@7.18.0)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)(sass@1.54.0) + packages/next-plugin-storybook: {} packages/next-polyfill-module: devDependencies: @@ -6714,10 +6710,6 @@ packages: resolution: {integrity: sha512-XQr74QaLeMiqhStEhLn1im9EOMnkypp7MZOwQhGzqp2Weu5eQJbpPxWxixxlYRKWPOmJjsk6qYfYH9kq43yc2w==} dev: true - /@next/env@13.5.3: - resolution: {integrity: sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==} - dev: false - /@next/react-refresh-utils@13.5.3(react-refresh@0.12.0)(webpack@5.86.0): resolution: {integrity: sha512-Y4wsqtdX+/QZ6W19N3y/YnuxAt/a79l/zYmRc2mwEplP0rIv6W3MBo3ePFUXOMVfmVesnOhfnZanaGiynZcFOg==} peerDependencies: @@ -6731,87 +6723,6 @@ packages: webpack: 5.86.0(@swc/core@1.3.85) dev: true - /@next/swc-darwin-arm64@13.5.3: - resolution: {integrity: sha512-6hiYNJxJmyYvvKGrVThzo4nTcqvqUTA/JvKim7Auaj33NexDqSNwN5YrrQu+QhZJCIpv2tULSHt+lf+rUflLSw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@next/swc-darwin-x64@13.5.3: - resolution: {integrity: sha512-UpBKxu2ob9scbpJyEq/xPgpdrgBgN3aLYlxyGqlYX5/KnwpJpFuIHU2lx8upQQ7L+MEmz+fA1XSgesoK92ppwQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-arm64-gnu@13.5.3: - resolution: {integrity: sha512-5AzM7Yx1Ky+oLY6pHs7tjONTF22JirDPd5Jw/3/NazJ73uGB05NqhGhB4SbeCchg7SlVYVBeRMrMSZwJwq/xoA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-arm64-musl@13.5.3: - resolution: {integrity: sha512-A/C1shbyUhj7wRtokmn73eBksjTM7fFQoY2v/0rTM5wehpkjQRLOXI8WJsag2uLhnZ4ii5OzR1rFPwoD9cvOgA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-x64-gnu@13.5.3: - resolution: {integrity: sha512-FubPuw/Boz8tKkk+5eOuDHOpk36F80rbgxlx4+xty/U71e3wZZxVYHfZXmf0IRToBn1Crb8WvLM9OYj/Ur815g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-linux-x64-musl@13.5.3: - resolution: {integrity: sha512-DPw8nFuM1uEpbX47tM3wiXIR0Qa+atSzs9Q3peY1urkhofx44o7E1svnq+a5Q0r8lAcssLrwiM+OyJJgV/oj7g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-arm64-msvc@13.5.3: - resolution: {integrity: sha512-zBPSP8cHL51Gub/YV8UUePW7AVGukp2D8JU93IHbVDu2qmhFAn9LWXiOOLKplZQKxnIPUkJTQAJDCWBWU4UWUA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-ia32-msvc@13.5.3: - resolution: {integrity: sha512-ONcL/lYyGUj4W37D4I2I450SZtSenmFAvapkJQNIJhrPMhzDU/AdfLkW98NvH1D2+7FXwe7yclf3+B7v28uzBQ==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: false - optional: true - - /@next/swc-win32-x64-msvc@13.5.3: - resolution: {integrity: sha512-2Vz2tYWaLqJvLcWbbTlJ5k9AN6JD7a5CN2pAeIzpbecK8ZF/yobA39cXtv6e+Z8c5UJuVOmaTldEAIxvsIux/Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false - optional: true - /@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3: resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} requiresBuild: true @@ -7291,6 +7202,7 @@ packages: /@opentelemetry/api@1.4.1: resolution: {integrity: sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==} engines: {node: '>=8.0.0'} + dev: true /@opentelemetry/core@1.15.2(@opentelemetry/api@1.4.1): resolution: {integrity: sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw==} @@ -19403,48 +19315,6 @@ packages: resolution: {integrity: sha1-yobR/ogoFpsBICCOPchCS524NCw=} dev: true - /next@13.5.3(@babel/core@7.18.0)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0)(sass@1.54.0): - resolution: {integrity: sha512-4Nt4HRLYDW/yRpJ/QR2t1v63UOMS55A38dnWv3UDOWGezuY0ZyFO1ABNbD7mulVzs9qVhgy2+ppjdsANpKP1mg==} - engines: {node: '>=16.14.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - sass: - optional: true - dependencies: - '@next/env': 13.5.3 - '@opentelemetry/api': 1.4.1 - '@swc/helpers': 0.5.2 - busboy: 1.6.0 - caniuse-lite: 1.0.30001406 - postcss: 8.4.14 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - sass: 1.54.0 - styled-jsx: 5.1.1(@babel/core@7.18.0)(react@18.2.0) - watchpack: 2.4.0 - zod: 3.21.4 - optionalDependencies: - '@next/swc-darwin-arm64': 13.5.3 - '@next/swc-darwin-x64': 13.5.3 - '@next/swc-linux-arm64-gnu': 13.5.3 - '@next/swc-linux-arm64-musl': 13.5.3 - '@next/swc-linux-x64-gnu': 13.5.3 - '@next/swc-linux-x64-musl': 13.5.3 - '@next/swc-win32-arm64-msvc': 13.5.3 - '@next/swc-win32-ia32-msvc': 13.5.3 - '@next/swc-win32-x64-msvc': 13.5.3 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - dev: false - /nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true @@ -26882,10 +26752,6 @@ packages: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} dev: true - /zod@3.21.4: - resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} - dev: false - /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: true diff --git a/test/e2e/app-dir/app/experimental-compile.test.ts b/test/e2e/app-dir/app/experimental-compile.test.ts new file mode 100644 index 0000000000..cc5c53b5d4 --- /dev/null +++ b/test/e2e/app-dir/app/experimental-compile.test.ts @@ -0,0 +1,9 @@ +import 'e2e-utils' + +process.env.NEXT_EXPERIMENTAL_COMPILE = '1' + +if ((global as any).isNextStart) { + require('./index.test') +} else { + it('should skip', () => {}) +} diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index 40134754d9..33831c4926 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -7,14 +7,19 @@ createNextDescribe( 'app dir', { files: __dirname, + buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE + ? 'pnpm next experimental-compile' + : undefined, }, ({ next, isNextDev: isDev, isNextStart, isNextDeploy }) => { if (isNextStart) { - it('should have correct size in build output', async () => { - expect(next.cliOutput).toMatch( - /\/dashboard\/another.*? [^0]{1,} [\w]{1,}B/ - ) - }) + if (!process.env.NEXT_EXPERIMENTAL_COMPILE) { + it('should have correct size in build output', async () => { + expect(next.cliOutput).toMatch( + /\/dashboard\/another.*? [^0]{1,} [\w]{1,}B/ + ) + }) + } it('should have correct preferredRegion values in manifest', async () => { const middlewareManifest = JSON.parse(