From 6376a84fa4751985946620520f03b3796e67c9f0 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Sat, 18 Oct 2025 12:44:16 -0700 Subject: [PATCH] [cache components]: show when cache components is enabled --- packages/next/src/build/index.ts | 12 +-- packages/next/src/server/config.ts | 9 --- packages/next/src/server/lib/app-info-log.ts | 29 +++++-- .../build-output-prerender.test.ts | 77 +++++++------------ 4 files changed, 56 insertions(+), 71 deletions(-) diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 4b9e62a333b9b..ef60947430628 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -1115,11 +1115,12 @@ export default async function build( ) // Always log next version first then start rest jobs - const { envInfo, experimentalFeatures } = await getStartServerInfo({ - dir, - dev: false, - debugPrerender, - }) + const { envInfo, experimentalFeatures, cacheComponents } = + await getStartServerInfo({ + dir, + dev: false, + debugPrerender, + }) logStartInfo({ networkUrl: null, @@ -1127,6 +1128,7 @@ export default async function build( envInfo, experimentalFeatures, logBundler: true, + cacheComponents, }) const typeCheckingOptions: Parameters[0] = { diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index c7b7e5d7ef8d1..6293d15a93a8e 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -1784,15 +1784,6 @@ function enforceExperimentalFeatures( (isDefaultConfig && !config.cacheComponents)) ) { config.cacheComponents = true - - if (configuredExperimentalFeatures) { - addConfiguredExperimentalFeature( - configuredExperimentalFeatures, - 'cacheComponents', - true, - 'enabled by `__NEXT_CACHE_COMPONENTS`' - ) - } } // TODO: Remove this once using the debug channel is the default. diff --git a/packages/next/src/server/lib/app-info-log.ts b/packages/next/src/server/lib/app-info-log.ts index 3eb505d136372..41cb8f6866d4a 100644 --- a/packages/next/src/server/lib/app-info-log.ts +++ b/packages/next/src/server/lib/app-info-log.ts @@ -14,28 +14,40 @@ export function logStartInfo({ envInfo, experimentalFeatures, logBundler, + cacheComponents, }: { networkUrl: string | null appUrl: string | null envInfo?: string[] experimentalFeatures?: ConfiguredExperimentalFeature[] logBundler: boolean + cacheComponents?: boolean }) { - let bundlerSuffix = '' + let versionSuffix = '' + const parts = [] + if (logBundler) { if (process.env.TURBOPACK) { - bundlerSuffix = ' (Turbopack)' + parts.push('Turbopack') } else if (process.env.NEXT_RSPACK) { - bundlerSuffix = ' (Rspack)' + parts.push('Rspack') } else { - bundlerSuffix = ' (webpack)' + parts.push('webpack') } } + if (cacheComponents) { + parts.push('Cache Components') + } + + if (parts.length > 0) { + versionSuffix = ` (${parts.join(', ')})` + } + Log.bootstrap( `${bold( purple(`${Log.prefixes.ready} Next.js ${process.env.__NEXT_VERSION}`) - )}${bundlerSuffix}` + )}${versionSuffix}` ) if (appUrl) { Log.bootstrap(`- Local: ${appUrl}`) @@ -91,9 +103,11 @@ export async function getStartServerInfo({ }): Promise<{ envInfo?: string[] experimentalFeatures?: ConfiguredExperimentalFeature[] + cacheComponents?: boolean }> { let experimentalFeatures: ConfiguredExperimentalFeature[] = [] - await loadConfig( + let cacheComponents = false + const config = await loadConfig( dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_BUILD, dir, { @@ -107,6 +121,8 @@ export async function getStartServerInfo({ } ) + cacheComponents = !!config.cacheComponents + // we need to reset env if we are going to create // the worker process with the esm loader so that the // initial env state is correct @@ -119,5 +135,6 @@ export async function getStartServerInfo({ return { envInfo, experimentalFeatures, + cacheComponents, } } diff --git a/test/production/app-dir/build-output-prerender/build-output-prerender.test.ts b/test/production/app-dir/build-output-prerender/build-output-prerender.test.ts index 94dd893ad5fa0..c48db001e3f18 100644 --- a/test/production/app-dir/build-output-prerender/build-output-prerender.test.ts +++ b/test/production/app-dir/build-output-prerender/build-output-prerender.test.ts @@ -18,59 +18,48 @@ describe('build-output-prerender', () => { beforeAll(() => next.build()) - // TODO: Re-enable this test once we move the cache components flag - it.skip('prints only the user-selected experimental flags (and the ones enabled via env variable)', async () => { + it('prints only the user-selected experimental flags (and the ones enabled via env variable)', async () => { if (cacheComponentsEnabled) { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (Turbopack) + "▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`)" `) } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (webpack) + "▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`)" `) } } else if (pprEnabled) { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (Turbopack) + "▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ ppr (enabled by \`__NEXT_EXPERIMENTAL_PPR\`)" `) } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (webpack) + "▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ ppr (enabled by \`__NEXT_EXPERIMENTAL_PPR\`)" `) } } else { if (isTurbopack) { - expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (Turbopack) - - Experiments (use with caution): - ✓ cacheComponents" - `) + expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot( + `"▲ Next.js x.y.z (Turbopack, Cache Components)"` + ) } else if (isRspack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (Rspack) - - Experiments (use with caution): - ✓ cacheComponents" + "▲ Next.js x.y.z (Rspack, Cache Components)" `) } else { - expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (webpack) - - Experiments (use with caution): - ✓ cacheComponents" - `) + expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot( + `"▲ Next.js x.y.z (webpack, Cache Components)"` + ) } } }) @@ -116,15 +105,13 @@ describe('build-output-prerender', () => { beforeAll(() => next.build()) - // TODO: Re-enable this test once we move the cache components flag - it.skip('prints a warning and the customized experimental flags', async () => { + it('prints a warning and the customized experimental flags', async () => { if (cacheComponentsEnabled) { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (Turbopack) + ▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`) @@ -133,9 +120,8 @@ describe('build-output-prerender', () => { } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (webpack) + ▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`) ⨯ serverMinification (disabled by \`--debug-prerender\`) @@ -146,9 +132,8 @@ describe('build-output-prerender', () => { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (Turbopack) + ▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ ppr (enabled by \`__NEXT_EXPERIMENTAL_PPR\`) ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`) @@ -157,9 +142,8 @@ describe('build-output-prerender', () => { } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (webpack) + ▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ✓ ppr (enabled by \`__NEXT_EXPERIMENTAL_PPR\`) ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ⨯ serverMinification (disabled by \`--debug-prerender\`) @@ -170,9 +154,8 @@ describe('build-output-prerender', () => { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (Turbopack) + ▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`) ⨯ turbopackMinify (disabled by \`--debug-prerender\`)" @@ -180,9 +163,8 @@ describe('build-output-prerender', () => { } else if (isRspack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (Rspack) + ▲ Next.js x.y.z (Rspack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ⨯ serverMinification (disabled by \`--debug-prerender\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`)" @@ -190,9 +172,8 @@ describe('build-output-prerender', () => { } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (webpack) + ▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ⨯ serverMinification (disabled by \`--debug-prerender\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`)" @@ -241,21 +222,18 @@ describe('build-output-prerender', () => { beforeAll(() => next.build()) - // TODO: Re-enable this test once we move the cache components flag - it.skip('prints no experimental flags (unless enabled via env variable)', async () => { + it('prints no experimental flags (unless enabled via env variable)', async () => { if (cacheComponentsEnabled) { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (Turbopack) + "▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents (enabled by \`__NEXT_CACHE_COMPONENTS\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`)" `) } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` - "▲ Next.js x.y.z (webpack) + "▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents (enabled by \`__NEXT_CACHE_COMPONENTS\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`)" `) } @@ -300,15 +278,13 @@ describe('build-output-prerender', () => { beforeAll(() => next.build()) - // TODO: Re-enable this test once we move the cache components flag - it.skip('prints a warning and the customized experimental flags', async () => { + it('prints a warning and the customized experimental flags', async () => { if (cacheComponentsEnabled) { if (isTurbopack) { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (Turbopack) + ▲ Next.js x.y.z (Turbopack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents (enabled by \`__NEXT_CACHE_COMPONENTS\`) ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`) ✓ serverSourceMaps (enabled by \`--debug-prerender\`) @@ -317,9 +293,8 @@ describe('build-output-prerender', () => { } else { expect(getPreambleOutput(next.cliOutput)).toMatchInlineSnapshot(` "⚠ Prerendering is running in debug mode. Note: This may affect performance and should not be used for production. - ▲ Next.js x.y.z (webpack) + ▲ Next.js x.y.z (webpack, Cache Components) - Experiments (use with caution): - ✓ cacheComponents (enabled by \`__NEXT_CACHE_COMPONENTS\`) ⨯ prerenderEarlyExit (disabled by \`--debug-prerender\`) ✓ reactDebugChannel (enabled by \`__NEXT_EXPERIMENTAL_DEBUG_CHANNEL\`) ⨯ serverMinification (disabled by \`--debug-prerender\`)