From 47d72b3ec0fccd23086716b7c082d9b44c46e7f9 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 1 Aug 2025 17:28:37 +0200 Subject: [PATCH 01/10] Refactor base-server --- packages/next/src/server/base-server.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 82c0c2d6a8dc30..cc637786d6acbc 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -45,6 +45,7 @@ import type { TLSSocket } from 'tls' import type { PathnameNormalizer } from './normalizers/request/pathname-normalizer' import type { InstrumentationModule } from './instrumentation/types' +import * as path from 'path' import { format as formatUrl, parse as parseUrl } from 'url' import { formatHostname } from './lib/format-hostname' import { @@ -444,7 +445,7 @@ export default abstract class Server< this.experimentalTestProxy = experimentalTestProxy this.serverOptions = options - this.dir = (require('path') as typeof import('path')).resolve(dir) + this.dir = path.resolve(dir) this.quiet = quiet this.loadEnvConfig({ dev }) @@ -458,10 +459,7 @@ export default abstract class Server< this.fetchHostname = formatHostname(this.hostname) } this.port = port - this.distDir = (require('path') as typeof import('path')).join( - this.dir, - this.nextConfig.distDir - ) + this.distDir = path.join(this.dir, this.nextConfig.distDir) this.publicDir = this.getPublicDir() this.hasStaticDir = !minimalMode && this.getHasStaticDir() @@ -2416,19 +2414,19 @@ export default abstract class Server< return null } - private stripNextDataPath(path: string, stripLocale = true) { - if (path.includes(this.buildId)) { - const splitPath = path.substring( - path.indexOf(this.buildId) + this.buildId.length + private stripNextDataPath(filePath: string, stripLocale = true) { + if (filePath.includes(this.buildId)) { + const splitPath = filePath.substring( + filePath.indexOf(this.buildId) + this.buildId.length ) - path = denormalizePagePath(splitPath.replace(/\.json$/, '')) + filePath = denormalizePagePath(splitPath.replace(/\.json$/, '')) } if (this.localeNormalizer && stripLocale) { - return this.localeNormalizer.normalize(path) + return this.localeNormalizer.normalize(filePath) } - return path + return filePath } // map the route to the actual bundle name From eb79a46c5ed808abcb359515cbb547485d29566a Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 4 Aug 2025 16:51:42 +0200 Subject: [PATCH 02/10] Add ignore comments --- packages/next/src/server/route-modules/route-module.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/next/src/server/route-modules/route-module.ts b/packages/next/src/server/route-modules/route-module.ts index 635837ec9f7a44..5992a6ed9728b5 100644 --- a/packages/next/src/server/route-modules/route-module.ts +++ b/packages/next/src/server/route-modules/route-module.ts @@ -152,6 +152,7 @@ export abstract class RouteModule< } else { const { join } = require('node:path') as typeof import('node:path') const absoluteProjectDir = join( + /* turbopackIgnore: true */ process.cwd(), getRequestMeta(req, 'relativeProjectDir') || this.relativeProjectDir ) @@ -390,6 +391,7 @@ export abstract class RouteModule< const { join } = require('node:path') as typeof import('node:path') const absoluteProjectDir = join( + /* turbopackIgnore: true */ process.cwd(), getRequestMeta(req, 'relativeProjectDir') || this.relativeProjectDir ) @@ -432,6 +434,7 @@ export abstract class RouteModule< } const { join } = require('node:path') as typeof import('node:path') const projectDir = join( + /* turbopackIgnore: true */ process.cwd(), getRequestMeta(req, 'relativeProjectDir') || this.relativeProjectDir ) @@ -539,6 +542,7 @@ export abstract class RouteModule< require('node:path') as typeof import('node:path') absoluteProjectDir = join( + /* turbopackIgnore: true */ process.cwd(), getRequestMeta(req, 'relativeProjectDir') || this.relativeProjectDir ) From ce2c62907f15f93b928208bd2a7fa38d175d010b Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 1 Aug 2025 18:33:25 +0200 Subject: [PATCH 03/10] Add ignore comments --- packages/next/src/server/base-server.ts | 7 +- packages/next/src/server/image-optimizer.ts | 14 ++-- packages/next/src/server/load-components.ts | 27 ++++++-- packages/next/src/server/next-server.ts | 75 ++++++++++++++++----- packages/next/src/server/next.ts | 15 +++-- packages/next/src/server/require.ts | 24 ++++--- 6 files changed, 123 insertions(+), 39 deletions(-) diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index cc637786d6acbc..2731f1fa53f775 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -445,7 +445,7 @@ export default abstract class Server< this.experimentalTestProxy = experimentalTestProxy this.serverOptions = options - this.dir = path.resolve(dir) + this.dir = path.resolve(/* turbopackIgnore: true */ dir) this.quiet = quiet this.loadEnvConfig({ dev }) @@ -459,7 +459,10 @@ export default abstract class Server< this.fetchHostname = formatHostname(this.hostname) } this.port = port - this.distDir = path.join(this.dir, this.nextConfig.distDir) + this.distDir = path.join( + /* turbopackIgnore: true */ this.dir, + this.nextConfig.distDir + ) this.publicDir = this.getPublicDir() this.hasStaticDir = !minimalMode && this.getHasStaticDir() diff --git a/packages/next/src/server/image-optimizer.ts b/packages/next/src/server/image-optimizer.ts index 1d9f79b014a83d..727e812b6ae7da 100644 --- a/packages/next/src/server/image-optimizer.ts +++ b/packages/next/src/server/image-optimizer.ts @@ -142,6 +142,7 @@ async function writeToCacheDir( upstreamEtag: string ) { const filename = join( + /* turbopackIgnore: true */ dir, `${maxAge}.${expireAt}.${etag}.${upstreamEtag}.${extension}` ) @@ -494,20 +495,25 @@ export class ImageOptimizerCache { distDir: string nextConfig: NextConfigComplete }) { - this.cacheDir = join(distDir, 'cache', 'images') + this.cacheDir = join(/* turbopackIgnore: true */ distDir, 'cache', 'images') this.nextConfig = nextConfig } async get(cacheKey: string): Promise { try { - const cacheDir = join(this.cacheDir, cacheKey) + const cacheDir = join(/* turbopackIgnore: true */ this.cacheDir, cacheKey) const files = await promises.readdir(cacheDir) const now = Date.now() for (const file of files) { const [maxAgeSt, expireAtSt, etag, upstreamEtag, extension] = file.split('.', 5) - const buffer = await promises.readFile(join(cacheDir, file)) + const buffer = await promises.readFile( + /* turbopackIgnore: true */ join( + /* turbopackIgnore: true */ cacheDir, + file + ) + ) const expireAt = Number(expireAtSt) const maxAge = Number(maxAgeSt) @@ -560,7 +566,7 @@ export class ImageOptimizerCache { try { await writeToCacheDir( - join(this.cacheDir, cacheKey), + join(/* turbopackIgnore: true */ this.cacheDir, cacheKey), value.extension, revalidate, expireAt, diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index 83b9483e82eb88..904c5f27ae29da 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -177,9 +177,13 @@ async function loadComponentsImpl({ let reactLoadableManifestPath if (!process.env.TURBOPACK) { - reactLoadableManifestPath = join(distDir, REACT_LOADABLE_MANIFEST) + reactLoadableManifestPath = join( + /* turbopackIgnore: true */ distDir, + REACT_LOADABLE_MANIFEST + ) } else if (isAppPath) { reactLoadableManifestPath = join( + /* turbopackIgnore: true */ distDir, 'server', 'app', @@ -188,6 +192,7 @@ async function loadComponentsImpl({ ) } else { reactLoadableManifestPath = join( + /* turbopackIgnore: true */ distDir, 'server', 'pages', @@ -213,7 +218,7 @@ async function loadComponentsImpl({ subresourceIntegrityManifest, ] = await Promise.all([ loadManifestWithRetries( - join(distDir, BUILD_MANIFEST), + join(/* turbopackIgnore: true */ distDir, BUILD_MANIFEST), manifestLoadAttempts ), tryLoadManifestWithRetries( @@ -224,12 +229,16 @@ async function loadComponentsImpl({ isAppPath || process.env.TURBOPACK ? undefined : loadManifestWithRetries( - join(distDir, `${DYNAMIC_CSS_MANIFEST}.json`), + join( + /* turbopackIgnore: true */ distDir, + `${DYNAMIC_CSS_MANIFEST}.json` + ), manifestLoadAttempts ).catch(() => undefined), isAppPath && hasClientManifest ? tryLoadClientReferenceManifest( join( + /* turbopackIgnore: true */ distDir, 'server', 'app', @@ -241,13 +250,21 @@ async function loadComponentsImpl({ : undefined, isAppPath ? loadManifestWithRetries( - join(distDir, 'server', SERVER_REFERENCE_MANIFEST + '.json'), + join( + /* turbopackIgnore: true */ distDir, + 'server', + SERVER_REFERENCE_MANIFEST + '.json' + ), manifestLoadAttempts ).catch(() => null) : null, sriEnabled ? loadManifestWithRetries>>( - join(distDir, 'server', SUBRESOURCE_INTEGRITY_MANIFEST + '.json') + join( + /* turbopackIgnore: true */ distDir, + 'server', + SUBRESOURCE_INTEGRITY_MANIFEST + '.json' + ) ).catch(() => undefined) : undefined, ]) diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 1d795882c6e28e..0e66b2a10e4c51 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -327,7 +327,10 @@ export default class NextNodeServer extends BaseServer< interceptTestApis() } - this.middlewareManifestPath = join(this.serverDistDir, MIDDLEWARE_MANIFEST) + this.middlewareManifestPath = join( + /* turbopackIgnore: true */ this.serverDistDir, + MIDDLEWARE_MANIFEST + ) // This is just optimization to fire prepare as soon as possible. It will be // properly awaited later. We add the catch here to ensure that it does not @@ -509,16 +512,21 @@ export default class NextNodeServer extends BaseServer< } protected getPublicDir(): string { - return join(this.dir, CLIENT_PUBLIC_FILES_PATH) + return join(/* turbopackIgnore: true */ this.dir, CLIENT_PUBLIC_FILES_PATH) } protected getHasStaticDir(): boolean { - return fs.existsSync(join(this.dir, 'static')) + return fs.existsSync( + /* turbopackIgnore: true */ join( + /* turbopackIgnore: true */ this.dir, + 'static' + ) + ) } protected getPagesManifest(): PagesManifest | undefined { return loadManifest( - join(this.serverDistDir, PAGES_MANIFEST) + join(/* turbopackIgnore: true */ this.serverDistDir, PAGES_MANIFEST) ) as PagesManifest } @@ -526,7 +534,7 @@ export default class NextNodeServer extends BaseServer< if (!this.enabledDirectories.app) return undefined return loadManifest( - join(this.serverDistDir, APP_PATHS_MANIFEST) + join(/* turbopackIgnore: true */ this.serverDistDir, APP_PATHS_MANIFEST) ) as PagesManifest } @@ -551,9 +559,14 @@ export default class NextNodeServer extends BaseServer< } protected getBuildId(): string { - const buildIdFile = join(this.distDir, BUILD_ID_FILE) + const buildIdFile = join( + /* turbopackIgnore: true */ this.distDir, + BUILD_ID_FILE + ) try { - return fs.readFileSync(buildIdFile, 'utf8').trim() + return fs + .readFileSync(/* turbopackIgnore: true */ buildIdFile, 'utf8') + .trim() } catch (err: any) { if (err.code === 'ENOENT') { throw new Error( @@ -931,7 +944,11 @@ export default class NextNodeServer extends BaseServer< protected getNextFontManifest(): NextFontManifest | undefined { return loadManifest( - join(this.distDir, 'server', NEXT_FONT_MANIFEST + '.json') + join( + /* turbopackIgnore: true */ this.distDir, + 'server', + NEXT_FONT_MANIFEST + '.json' + ) ) as NextFontManifest } @@ -1495,17 +1512,25 @@ export default class NextNodeServer extends BaseServer< return { name: pageInfo.name, - paths: pageInfo.files.map((file) => join(this.distDir, file)), + paths: pageInfo.files.map((file) => + join(/* turbopackIgnore: true */ this.distDir, file) + ), wasm: (pageInfo.wasm ?? []).map((binding) => ({ ...binding, - filePath: join(this.distDir, binding.filePath), + filePath: join( + /* turbopackIgnore: true */ this.distDir, + binding.filePath + ), })), assets: pageInfo.assets && pageInfo.assets.map((binding) => { return { ...binding, - filePath: join(this.distDir, binding.filePath), + filePath: join( + /* turbopackIgnore: true */ this.distDir, + binding.filePath + ), } }), env: pageInfo.env, @@ -1517,14 +1542,26 @@ export default class NextNodeServer extends BaseServer< try { const functionsConfig = this.renderOpts.dev ? {} - : require(join(this.distDir, 'server', FUNCTIONS_CONFIG_MANIFEST)) + : require( + join( + /* turbopackIgnore: true */ this.distDir, + 'server', + FUNCTIONS_CONFIG_MANIFEST + ) + ) if ( this.renderOpts.dev || functionsConfig?.functions?.['/_middleware'] ) { // if used with top level await, this will be a promise - return require(join(this.distDir, 'server', 'middleware.js')) + return require( + join( + /* turbopackIgnore: true */ this.distDir, + 'server', + 'middleware.js' + ) + ) } } catch (err) { if ( @@ -1861,7 +1898,7 @@ export default class NextNodeServer extends BaseServer< } this._cachedPreviewManifest = loadManifest( - join(this.distDir, PRERENDER_MANIFEST) + join(/* turbopackIgnore: true */ this.distDir, PRERENDER_MANIFEST) ) as PrerenderManifest return this._cachedPreviewManifest @@ -1870,7 +1907,10 @@ export default class NextNodeServer extends BaseServer< protected getRoutesManifest(): NormalizedRouteManifest | undefined { return getTracer().trace( NextNodeServerSpan.getRoutesManifest, - () => loadManifest(join(this.distDir, ROUTES_MANIFEST)) as RoutesManifest + () => + loadManifest( + join(/* turbopackIgnore: true */ this.distDir, ROUTES_MANIFEST) + ) as RoutesManifest ) } @@ -2032,7 +2072,10 @@ export default class NextNodeServer extends BaseServer< if (this._serverDistDir) { return this._serverDistDir } - const serverDistDir = join(this.distDir, SERVER_DIRECTORY) + const serverDistDir = join( + /* turbopackIgnore: true */ this.distDir, + SERVER_DIRECTORY + ) this._serverDistDir = serverDistDir return serverDistDir } diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index 14d457f485918e..1c6c807d7ddf63 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -14,7 +14,7 @@ import './node-polyfill-crypto' import type { default as NextNodeServer } from './next-server' import * as log from '../build/output/log' import loadConfig from './config' -import path, { resolve } from 'path' +import path from 'path' import { NON_STANDARD_NODE_ENV } from '../lib/constants' import { PHASE_DEVELOPMENT_SERVER, @@ -247,7 +247,9 @@ export class NextServer implements NextWrapperServer { } private async [SYMBOL_LOAD_CONFIG]() { - const dir = resolve(this.options.dir || '.') + const dir = path.resolve( + /* turbopackIgnore: true */ this.options.dir || '.' + ) const config = await loadConfig( this.options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER, @@ -262,7 +264,12 @@ export class NextServer implements NextWrapperServer { if (!this.options.dev) { try { const serializedConfig = require( - path.join(dir, config.distDir, SERVER_FILES_MANIFEST) + /* turbopackIgnore: true */ + path.join( + /* turbopackIgnore: true */ dir, + config.distDir, + SERVER_FILES_MANIFEST + ) ).config config.experimental.isExperimentalCompile = @@ -549,7 +556,7 @@ function createServer( // When the caller is a custom server (using next()). if (options.customServer !== false) { - const dir = resolve(options.dir || '.') + const dir = path.resolve(/* turbopackIgnore: true */ options.dir || '.') return new NextCustomServer({ ...options, diff --git a/packages/next/src/server/require.ts b/packages/next/src/server/require.ts index 67e692bc23d30c..9bcda1c14cdd3b 100644 --- a/packages/next/src/server/require.ts +++ b/packages/next/src/server/require.ts @@ -29,17 +29,23 @@ export function getMaybePagePath( // If we have a cached path, we can return it directly. if (pagePath) return pagePath - const serverBuildPath = path.join(distDir, SERVER_DIRECTORY) + const serverBuildPath = path.join( + /* turbopackIgnore: true */ distDir, + SERVER_DIRECTORY + ) let appPathsManifest: undefined | PagesManifest if (isAppPath) { appPathsManifest = loadManifest( - path.join(serverBuildPath, APP_PATHS_MANIFEST), + path.join( + /* turbopackIgnore: true */ serverBuildPath, + APP_PATHS_MANIFEST + ), !isDev ) as PagesManifest } const pagesManifest = loadManifest( - path.join(serverBuildPath, PAGES_MANIFEST), + path.join(/* turbopackIgnore: true */ serverBuildPath, PAGES_MANIFEST), !isDev ) as PagesManifest @@ -85,7 +91,7 @@ export function getMaybePagePath( return pagePath } - pagePath = path.join(serverBuildPath, pagePath) + pagePath = path.join(/* turbopackIgnore: true */ serverBuildPath, pagePath) pagePathCache?.set(cacheKey, pagePath) return pagePath @@ -113,14 +119,16 @@ export async function requirePage( ): Promise { const pagePath = getPagePath(page, distDir, undefined, isAppPath) if (pagePath.endsWith('.html')) { - return promises.readFile(pagePath, 'utf8').catch((err) => { - throw new MissingStaticPage(page, err.message) - }) + return promises + .readFile(/* turbopackIgnore: true */ pagePath, 'utf8') + .catch((err) => { + throw new MissingStaticPage(page, err.message) + }) } const mod = process.env.NEXT_MINIMAL ? // @ts-ignore __non_webpack_require__(pagePath) - : require(pagePath) + : require(/* turbopackIgnore: true */ pagePath) return mod } From f224072626dd7c86443116c930b565478a8e31b6 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:27:43 +0200 Subject: [PATCH 04/10] next-server NFT in Turbopack --- crates/napi/src/next_api/project.rs | 10 +- crates/next-api/src/lib.rs | 1 + crates/next-api/src/next_server_nft.rs | 340 ++++++++++++++++++ .../visit_client_reference.rs | 6 +- crates/next-core/src/next_config.rs | 5 + crates/next-core/src/next_server/mod.rs | 2 +- turbopack/crates/turbopack/src/lib.rs | 2 +- 7 files changed, 360 insertions(+), 6 deletions(-) create mode 100644 crates/next-api/src/next_server_nft.rs diff --git a/crates/napi/src/next_api/project.rs b/crates/napi/src/next_api/project.rs index d8b0e99de13d7b..70917b4d8d02d9 100644 --- a/crates/napi/src/next_api/project.rs +++ b/crates/napi/src/next_api/project.rs @@ -9,6 +9,7 @@ use napi::{ }; use next_api::{ entrypoints::Entrypoints, + next_server_nft::next_server_nft_assets, operation::{ EntrypointsOperation, InstrumentationOperation, MiddlewareOperation, OptionEndpoint, RouteOperation, @@ -988,7 +989,14 @@ async fn output_assets_operation( .flat_map(|assets| assets.iter().copied()) .collect(); - Ok(Vc::cell(output_assets.into_iter().collect())) + let nft = next_server_nft_assets(container.project()).await?; + + Ok(Vc::cell( + output_assets + .into_iter() + .chain(nft.iter().copied()) + .collect(), + )) } #[napi(ts_return_type = "{ __napiType: \"RootTask\" }")] diff --git a/crates/next-api/src/lib.rs b/crates/next-api/src/lib.rs index 17360fdb01d215..84499a4a5488b8 100644 --- a/crates/next-api/src/lib.rs +++ b/crates/next-api/src/lib.rs @@ -13,6 +13,7 @@ mod instrumentation; mod loadable_manifest; mod middleware; mod module_graph; +pub mod next_server_nft; mod nft_json; pub mod operation; mod pages; diff --git a/crates/next-api/src/next_server_nft.rs b/crates/next-api/src/next_server_nft.rs new file mode 100644 index 00000000000000..7e8aeb80e76ccf --- /dev/null +++ b/crates/next-api/src/next_server_nft.rs @@ -0,0 +1,340 @@ +use std::collections::BTreeSet; + +use anyhow::{Context, Result, bail}; +use either::Either; +use next_core::{get_next_package, next_server::get_tracing_compile_time_info}; +use serde_json::{Value, json}; +use tracing::{Level, instrument}; +use turbo_rcstr::RcStr; +use turbo_tasks::{ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, Vc}; +use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, File, FileSystemPath, glob::Glob}; +use turbopack::externals_tracing_module_context; +use turbopack_core::{ + asset::{Asset, AssetContent}, + context::AssetContext, + file_source::FileSource, + module::Module, + output::{OutputAsset, OutputAssets}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, + resolve::{ExternalType, origin::PlainResolveOrigin, parse::Request}, + traced_asset::TracedAsset, +}; +use turbopack_ecmascript::resolve::cjs_resolve; + +use crate::{nft_json::all_assets_from_entries_filtered, project::Project}; + +#[instrument(level = Level::INFO, skip_all)] +#[turbo_tasks::function] +pub async fn next_server_nft_assets(project: Vc) -> Result> { + let is_standalone = *project.next_config().is_standalone().await?; + let has_next_support = *project.next_config().ci_has_next_support().await?; + + let asset_context = Vc::upcast(externals_tracing_module_context( + ExternalType::CommonJs, + get_tracing_compile_time_info(), + )); + + let project_path = project.project_path().owned().await?; + + let next_resolve_origin = Vc::upcast(PlainResolveOrigin::new( + asset_context, + get_next_package(project_path.clone()).await?.join("_")?, + )); + + let resolve_entry = async |path: &str| { + Ok(cjs_resolve( + next_resolve_origin, + Request::parse_string(path.into()), + CommonJsReferenceSubType::Undefined, + None, + false, + ) + .primary_modules() + .await? + .into_iter() + .map(|m| **m)) + }; + + let cache_handler = project + .next_config() + .cache_handler(project_path.clone()) + .await?; + let cache_handlers = project + .next_config() + .experimental_cache_handlers(project_path.clone()) + .await?; + + // These are used by packages/next/src/server/require-hook.ts + let shared_entries: Vec>> = + ["styled-jsx", "styled-jsx/style", "styled-jsx/style.js"] + .into_iter() + .map(resolve_entry) + .try_flat_join() + .await?; + + let cache_handler_entries: Vec>> = cache_handler + .into_iter() + .chain(cache_handlers.into_iter()) + .map(|f| { + asset_context + .process( + Vc::upcast(FileSource::new(f.clone())), + ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined), + ) + .module() + }) + .collect(); + + let server_entries = shared_entries + .iter() + .chain(cache_handler_entries.iter()) + .copied() + .chain(if is_standalone { + Either::Left( + resolve_entry("next/dist/server/lib/start-server") + .await? + .chain(resolve_entry("next/dist/server/next").await?) + .chain(resolve_entry("next/dist/server/require-hook").await?), + ) + } else { + Either::Right(std::iter::empty()) + }) + .chain(resolve_entry("next/dist/server/next-server").await?) + .map(|m| Vc::upcast::>(TracedAsset::new(m)).to_resolved()) + .try_join() + .await?; + + let minimal_server_entries = shared_entries + .iter() + .chain(cache_handler_entries.iter()) + .copied() + .chain(resolve_entry("next/dist/compiled/next-server/server.runtime.prod").await?) + .map(|m| Vc::upcast::>(TracedAsset::new(m)).to_resolved()) + .try_join() + .await?; + + let output_file_tracing_excludes = project.next_config().output_file_tracing_excludes().await?; + let mut additional_ignores = BTreeSet::new(); + if let Some(output_file_tracing_excludes) = output_file_tracing_excludes + .as_ref() + .and_then(Value::as_object) + { + for (glob_pattern, exclude_patterns) in output_file_tracing_excludes { + // Check if the route matches the glob pattern + let glob = Glob::new(RcStr::from(glob_pattern.clone()), Default::default()).await?; + if glob.matches("next-server") + && let Some(patterns) = exclude_patterns.as_array() + { + for pattern in patterns { + if let Some(pattern_str) = pattern.as_str() { + additional_ignores.insert(pattern_str); + } + } + } + } + } + + let server_ignores_glob = [ + "**/node_modules/react{,-dom,-server-dom-turbopack}/**/*.development.js", + "**/*.d.ts", + "**/*.map", + "**/next/dist/pages/**/*", + "**/next/dist/compiled/next-server/**/*.dev.js", + "**/next/dist/compiled/webpack/*", + "**/node_modules/webpack5/**/*", + "**/next/dist/server/lib/route-resolver*", + "**/next/dist/compiled/semver/semver/**/*.js", + "**/next/dist/compiled/jest-worker/**/*", + // Turbopack doesn't support AMP + "**/next/dist/compiled/@ampproject/toolbox-optimizer/**/*", + // -- The following were added for Turbopack specifically -- + // client/components/use-action-queue.ts has a process.env.NODE_ENV guard, but we can't set that due to React: https://github.com/vercel/next.js/pull/75254 + "**/next/dist/next-devtools/userspace/use-app-dev-rendering-indicator.js", + // client/components/app-router.js has a process.env.NODE_ENV guard, but we can't set that. + "**/next/dist/client/dev/hot-reloader/app/hot-reloader-app.js", + // server/lib/router-server.js doesn't guard this require: + "**/next/dist/server/lib/router-utils/setup-dev-bundler.js", + // server/next.js doesn't guard this require + "**/next/dist/server/dev/next-dev-server.js", + // next/dist/compiled/babel* pulls in this, even we never actually transpile with Babel + "**/next/dist/compiled/browserslist/**", + ] + .into_iter() + .chain(additional_ignores) + .chain( + if has_next_support { + Some(["**/node_modules/sharp/**/*", "**/@img/sharp-libvips*/**/*"]).into_iter() + } else { + None.into_iter() + } + .flatten(), + ) + .chain(if has_next_support { + // only ignore image-optimizer code when + // this is being handled outside of next-server + Some("**/next/dist/server/image-optimizer.js").into_iter() + } else { + None.into_iter() + }) + .chain( + if is_standalone { + None.into_iter() + } else { + Some(["**/*/next/dist/server/next.js", "**/*/next/dist/bin/next"]).into_iter() + } + .flatten(), + ) + .map(|g| Glob::new(g.into(), Default::default())) + .collect::>(); + + let minimal_server_ignores_glob = Glob::alternatives( + server_ignores_glob + .iter() + .copied() + .chain( + [ + "**/next/dist/compiled/edge-runtime/**/*", + "**/next/dist/server/web/sandbox/**/*", + "**/next/dist/server/post-process.js", + ] + .into_iter() + .map(|g| Glob::new(g.into(), Default::default())), + ) + .collect(), + ); + + Ok(Vc::cell(vec![ + ResolvedVc::upcast( + ServerNftJsonAsset::new( + project, + RcStr::from("next-server.turbo"), + Vc::cell(server_entries), + Glob::alternatives(server_ignores_glob), + ) + .to_resolved() + .await?, + ), + ResolvedVc::upcast( + ServerNftJsonAsset::new( + project, + RcStr::from("next-minimal-server.turbo"), + Vc::cell(minimal_server_entries), + minimal_server_ignores_glob, + ) + .to_resolved() + .await?, + ), + ])) +} + +#[turbo_tasks::value] +pub struct ServerNftJsonAsset { + project: ResolvedVc, + name: RcStr, + entries: ResolvedVc, + ignores: ResolvedVc, +} + +#[turbo_tasks::value_impl] +impl ServerNftJsonAsset { + #[turbo_tasks::function] + pub fn new( + project: ResolvedVc, + name: RcStr, + entries: ResolvedVc, + ignores: ResolvedVc, + ) -> Vc { + ServerNftJsonAsset { + project, + name, + entries, + ignores, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for ServerNftJsonAsset { + #[turbo_tasks::function] + async fn path(&self) -> Result> { + Ok(self + .project + .node_root() + .await? + .join(&format!("{}.js.nft.json", self.name))? + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Asset for ServerNftJsonAsset { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + // Example: [project]/apps/my-website/.next/ + let base_dir = self + .project + .project_root_path() + .await? + .join(&self.project.node_root().await?.path)?; + + let mut server_output_assets = + all_assets_from_entries_filtered(*self.entries, None, Some(*self.ignores)) + .await? + .iter() + .map(async |m| { + base_dir + .get_relative_path_to(&*m.path().await?) + .context("failed to compute relative path for server nft.json") + }) + .try_join() + .await?; + + // A few hardcoded files (not recursive) + server_output_assets.push("./package.json".into()); + + let next_dir = get_next_package(self.project.project_path().owned().await?).await?; + for ty in ["app-page", "pages"] { + let dir = next_dir.join(&format!("dist/server/route-modules/{ty}"))?; + let module_path = dir.join("module.compiled.js")?; + server_output_assets.push( + base_dir + .get_relative_path_to(&module_path) + .context("failed to compute relative path for server nft.json")?, + ); + + let contexts_dir = dir.join("vendored/contexts")?; + let DirectoryContent::Entries(contexts_files) = &*contexts_dir.read_dir().await? else { + bail!( + "Expected contexts directory to be a directory, found: {:?}", + contexts_dir + ); + }; + for (_, entry) in contexts_files { + let DirectoryEntry::File(file) = entry else { + continue; + }; + if file.extension() == "js" { + server_output_assets.push( + base_dir + .get_relative_path_to(file) + .context("failed to compute relative path for server nft.json")?, + ) + } + } + } + + server_output_assets.sort(); + // Dedupe as some entries may be duplicates: a file might be referenced multiple times, + // e.g. as a RawModule (from an FS operation) and as an EcmascriptModuleAsset because it + // was required. + server_output_assets.dedup(); + + let json = json!({ + "version": 1, + "files": server_output_assets + }); + + Ok(AssetContent::file(File::from(json.to_string()).into())) + } +} diff --git a/crates/next-core/src/next_client_reference/visit_client_reference.rs b/crates/next-core/src/next_client_reference/visit_client_reference.rs index 614f3d6efeb234..f0a2862e2c2df7 100644 --- a/crates/next-core/src/next_client_reference/visit_client_reference.rs +++ b/crates/next-core/src/next_client_reference/visit_client_reference.rs @@ -266,13 +266,13 @@ impl Visit for FindServerEntries { tracing::info_span!("client reference") } FindServerEntriesNode::Internal(_, name) => { - tracing::info_span!("module", name = name.to_string()) + tracing::info_span!("module", name = display(name)) } FindServerEntriesNode::ServerUtilEntry(_, name) => { - tracing::info_span!("server util", name = name.to_string()) + tracing::info_span!("server util", name = display(name)) } FindServerEntriesNode::ServerComponentEntry(_, name) => { - tracing::info_span!("layout segment", name = name.to_string()) + tracing::info_span!("layout segment", name = display(name)) } } } diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index ed9221b9b2bdcf..8c129230b6aa32 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -1330,6 +1330,11 @@ impl NextConfig { Vc::cell(self.output == Some(OutputType::Standalone)) } + #[turbo_tasks::function] + pub fn ci_has_next_support(&self) -> Vc { + Vc::cell(self.env.contains_key("NOW_BUILDER")) + } + #[turbo_tasks::function] pub fn cache_handler(&self, project_path: FileSystemPath) -> Result> { if let Some(handler) = &self.cache_handler { diff --git a/crates/next-core/src/next_server/mod.rs b/crates/next-core/src/next_server/mod.rs index c2f97a515ecdbc..6980c2a73b8b11 100644 --- a/crates/next-core/src/next_server/mod.rs +++ b/crates/next-core/src/next_server/mod.rs @@ -6,5 +6,5 @@ pub use context::{ ServerChunkingContextOptions, ServerContextType, get_server_chunking_context, get_server_chunking_context_with_client_assets, get_server_compile_time_info, get_server_module_options_context, get_server_resolve_options_context, - get_server_runtime_entries, + get_server_runtime_entries, get_tracing_compile_time_info, }; diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs index 11dd2d331b38c7..ab71efcb1474eb 100644 --- a/turbopack/crates/turbopack/src/lib.rs +++ b/turbopack/crates/turbopack/src/lib.rs @@ -672,7 +672,7 @@ async fn process_default_internal( } #[turbo_tasks::function] -async fn externals_tracing_module_context( +pub async fn externals_tracing_module_context( ty: ExternalType, compile_time_info: Vc, ) -> Result> { From 231409b504811158b943e5300647d83c7a833b52 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:14:45 +0200 Subject: [PATCH 05/10] Switch over --- crates/next-api/src/next_server_nft.rs | 4 ++-- packages/next/src/build/collect-build-traces.ts | 6 ++++-- packages/next/src/build/index.ts | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/next-api/src/next_server_nft.rs b/crates/next-api/src/next_server_nft.rs index 7e8aeb80e76ccf..574e28586b6a7a 100644 --- a/crates/next-api/src/next_server_nft.rs +++ b/crates/next-api/src/next_server_nft.rs @@ -207,7 +207,7 @@ pub async fn next_server_nft_assets(project: Vc) -> Result) -> Result { const nextServerTraceOutput = path.join( distDir, - 'next-server.js.nft.json' + isTurbopack ? 'next-server.ref.js.nft.json' : 'next-server.js.nft.json' ) const nextMinimalTraceOutput = path.join( distDir, - 'next-minimal-server.js.nft.json' + isTurbopack + ? 'next-minimal-server.ref.js.nft.json' + : 'next-minimal-server.js.nft.json' ) const root = outputFileTracingRoot diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 98445016602e5b..400782a683f9e6 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -2653,7 +2653,7 @@ export default async function build( hasSsrAmpPages, buildTraceContext, outputFileTracingRoot, - isTurbopack: true, + isTurbopack, }).catch((err) => { console.error(err) process.exit(1) From 3bff755c2b6f31f4240022fcb1f117f9e198fbad Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 22 Aug 2025 18:57:36 +0200 Subject: [PATCH 06/10] Add snapshot test --- .../production/next-server-nft/app/layout.tsx | 7 + test/production/next-server-nft/app/page.tsx | 3 + .../next-server-nft/next-server-nft.test.ts | 741 ++++++++++++++++++ .../production/next-server-nft/next.config.js | 6 + 4 files changed, 757 insertions(+) create mode 100644 test/production/next-server-nft/app/layout.tsx create mode 100644 test/production/next-server-nft/app/page.tsx create mode 100644 test/production/next-server-nft/next-server-nft.test.ts create mode 100644 test/production/next-server-nft/next.config.js diff --git a/test/production/next-server-nft/app/layout.tsx b/test/production/next-server-nft/app/layout.tsx new file mode 100644 index 00000000000000..e7077399c03ce1 --- /dev/null +++ b/test/production/next-server-nft/app/layout.tsx @@ -0,0 +1,7 @@ +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/production/next-server-nft/app/page.tsx b/test/production/next-server-nft/app/page.tsx new file mode 100644 index 00000000000000..8afb7372a1d520 --- /dev/null +++ b/test/production/next-server-nft/app/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return 'Hello' +} diff --git a/test/production/next-server-nft/next-server-nft.test.ts b/test/production/next-server-nft/next-server-nft.test.ts new file mode 100644 index 00000000000000..cef37121417fdb --- /dev/null +++ b/test/production/next-server-nft/next-server-nft.test.ts @@ -0,0 +1,741 @@ +import { nextTestSetup } from 'e2e-utils' +import path from 'path' +import fs from 'fs' + +// Only run this test for Turbopack as it is more conservative (i.e. aggressive) in including +// referenced files and might include too many. (The Webpack snapshots would different slightly from +// the Turbopack ones below.) +// +// This test is not meant for testing correctness (which is done by the behavioral tests), but as a +// regression test to ensure that some stray `path.join` doesn't cause all of the Next.js package to +// get included. +;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)( + 'next-server-nft', + () => { + const { next, skipped } = nextTestSetup({ + files: __dirname, + skipDeployment: true, + }) + + if (skipped) { + return + } + + async function readNormalizedNFT(name) { + let data = await next.readJSON(name) + let result = [ + ...new Set( + data.files + .filter((file: string) => { + // They are important, but they are never actually included by themselves but rather as + // part of some JS files in the same directory tree, which are higher-signal for the + // screenshot below. + if (file.endsWith('/package.json')) { + return false + } + + // Filter out the many symlinks that power node_modules + let fileAbsolute = path.join(next.testDir, name, '..', file) + if (fs.lstatSync(fileAbsolute).isSymbolicLink()) { + return false + } + return true + }) + .map((file: string) => { + // Normalize sharp, different architectures have different files + if (file.includes('/node_modules/@img/sharp-libvips-')) { + return '@img/sharp-libvips-*' + } + if ( + file.match( + /\/node_modules\/@img\/sharp-\w+-\w+\/lib\/sharp-\w+-\w+.node$/ + ) + ) { + return '@img/sharp-*/sharp-*.node' + } + + // Strip double node_modules to simplify output + let firstNodeModules = file.indexOf('/node_modules/') + let lastNodeModules = file.lastIndexOf('/node_modules/') + if (firstNodeModules !== lastNodeModules) { + return file.slice(lastNodeModules) + } + + return file + }) + ), + ] + result.sort() + return result + } + + it('should not trace too many files in next-server.js.nft.json', async () => { + let trace = await readNormalizedNFT('.next/next-server.js.nft.json') + expect(trace).toMatchInlineSnapshot(` + [ + "/node_modules/@next/env/dist/index.js", + "/node_modules/@swc/helpers/cjs/_class_private_field_loose_base.cjs", + "/node_modules/@swc/helpers/cjs/_class_private_field_loose_key.cjs", + "/node_modules/@swc/helpers/cjs/_interop_require_default.cjs", + "/node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs", + "/node_modules/client-only/index.js", + "/node_modules/color-convert/conversions.js", + "/node_modules/color-convert/index.js", + "/node_modules/color-convert/route.js", + "/node_modules/color-name/index.js", + "/node_modules/color-string/index.js", + "/node_modules/color/index.js", + "/node_modules/detect-libc/lib/detect-libc.js", + "/node_modules/detect-libc/lib/filesystem.js", + "/node_modules/detect-libc/lib/process.js", + "/node_modules/is-arrayish/index.js", + "/node_modules/next/dist/build/output/log.js", + "/node_modules/next/dist/build/segment-config/app/app-segment-config.js", + "/node_modules/next/dist/build/segment-config/app/app-segments.js", + "/node_modules/next/dist/build/static-paths/utils.js", + "/node_modules/next/dist/client/add-base-path.js", + "/node_modules/next/dist/client/app-build-id.js", + "/node_modules/next/dist/client/app-call-server.js", + "/node_modules/next/dist/client/app-find-source-map-url.js", + "/node_modules/next/dist/client/assign-location.js", + "/node_modules/next/dist/client/components/app-router-announcer.js", + "/node_modules/next/dist/client/components/app-router-headers.js", + "/node_modules/next/dist/client/components/app-router-instance.js", + "/node_modules/next/dist/client/components/app-router.js", + "/node_modules/next/dist/client/components/builtin/default.js", + "/node_modules/next/dist/client/components/builtin/global-error.js", + "/node_modules/next/dist/client/components/dev-root-http-access-fallback-boundary.js", + "/node_modules/next/dist/client/components/error-boundary.js", + "/node_modules/next/dist/client/components/errors/graceful-degrade-boundary.js", + "/node_modules/next/dist/client/components/errors/root-error-boundary.js", + "/node_modules/next/dist/client/components/forbidden.js", + "/node_modules/next/dist/client/components/handle-isr-error.js", + "/node_modules/next/dist/client/components/hooks-server-context.js", + "/node_modules/next/dist/client/components/http-access-fallback/error-boundary.js", + "/node_modules/next/dist/client/components/http-access-fallback/http-access-fallback.js", + "/node_modules/next/dist/client/components/is-next-router-error.js", + "/node_modules/next/dist/client/components/links.js", + "/node_modules/next/dist/client/components/match-segments.js", + "/node_modules/next/dist/client/components/nav-failure-handler.js", + "/node_modules/next/dist/client/components/navigation-untracked.js", + "/node_modules/next/dist/client/components/navigation.js", + "/node_modules/next/dist/client/components/navigation.react-server.js", + "/node_modules/next/dist/client/components/not-found.js", + "/node_modules/next/dist/client/components/promise-queue.js", + "/node_modules/next/dist/client/components/redirect-boundary.js", + "/node_modules/next/dist/client/components/redirect-error.js", + "/node_modules/next/dist/client/components/redirect-status-code.js", + "/node_modules/next/dist/client/components/redirect.js", + "/node_modules/next/dist/client/components/router-reducer/aliased-prefetch-navigations.js", + "/node_modules/next/dist/client/components/router-reducer/apply-flight-data.js", + "/node_modules/next/dist/client/components/router-reducer/apply-router-state-patch-to-tree.js", + "/node_modules/next/dist/client/components/router-reducer/clear-cache-node-data-for-segment-path.js", + "/node_modules/next/dist/client/components/router-reducer/compute-changed-path.js", + "/node_modules/next/dist/client/components/router-reducer/create-href-from-url.js", + "/node_modules/next/dist/client/components/router-reducer/create-initial-router-state.js", + "/node_modules/next/dist/client/components/router-reducer/create-router-cache-key.js", + "/node_modules/next/dist/client/components/router-reducer/fetch-server-response.js", + "/node_modules/next/dist/client/components/router-reducer/fill-cache-with-new-subtree-data.js", + "/node_modules/next/dist/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.js", + "/node_modules/next/dist/client/components/router-reducer/handle-mutable.js", + "/node_modules/next/dist/client/components/router-reducer/handle-segment-mismatch.js", + "/node_modules/next/dist/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.js", + "/node_modules/next/dist/client/components/router-reducer/invalidate-cache-by-router-state.js", + "/node_modules/next/dist/client/components/router-reducer/is-navigating-to-new-root-layout.js", + "/node_modules/next/dist/client/components/router-reducer/ppr-navigations.js", + "/node_modules/next/dist/client/components/router-reducer/prefetch-cache-utils.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/find-head-in-cache.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/get-segment-value.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/has-interception-route-in-current-tree.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/hmr-refresh-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/navigate-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/prefetch-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/refresh-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/restore-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/server-action-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/reducers/server-patch-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/refetch-inactive-parallel-segments.js", + "/node_modules/next/dist/client/components/router-reducer/router-reducer-types.js", + "/node_modules/next/dist/client/components/router-reducer/router-reducer.js", + "/node_modules/next/dist/client/components/router-reducer/set-cache-busting-search-param.js", + "/node_modules/next/dist/client/components/router-reducer/should-hard-navigate.js", + "/node_modules/next/dist/client/components/segment-cache-impl/cache-key.js", + "/node_modules/next/dist/client/components/segment-cache-impl/cache.js", + "/node_modules/next/dist/client/components/segment-cache-impl/lru.js", + "/node_modules/next/dist/client/components/segment-cache-impl/navigation.js", + "/node_modules/next/dist/client/components/segment-cache-impl/prefetch.js", + "/node_modules/next/dist/client/components/segment-cache-impl/scheduler.js", + "/node_modules/next/dist/client/components/segment-cache-impl/tuple-map.js", + "/node_modules/next/dist/client/components/segment-cache.js", + "/node_modules/next/dist/client/components/static-generation-bailout.js", + "/node_modules/next/dist/client/components/unauthorized.js", + "/node_modules/next/dist/client/components/unrecognized-action-error.js", + "/node_modules/next/dist/client/components/unresolved-thenable.js", + "/node_modules/next/dist/client/components/unstable-rethrow.browser.js", + "/node_modules/next/dist/client/components/unstable-rethrow.js", + "/node_modules/next/dist/client/components/unstable-rethrow.server.js", + "/node_modules/next/dist/client/components/use-action-queue.js", + "/node_modules/next/dist/client/flight-data-helpers.js", + "/node_modules/next/dist/client/has-base-path.js", + "/node_modules/next/dist/client/normalize-trailing-slash.js", + "/node_modules/next/dist/client/remove-base-path.js", + "/node_modules/next/dist/client/route-params.js", + "/node_modules/next/dist/compiled/@edge-runtime/cookies/index.js", + "/node_modules/next/dist/compiled/@hapi/accept/index.js", + "/node_modules/next/dist/compiled/@mswjs/interceptors/ClientRequest/index.js", + "/node_modules/next/dist/compiled/@opentelemetry/api/index.js", + "/node_modules/next/dist/compiled/babel-packages/packages-bundle.js", + "/node_modules/next/dist/compiled/babel/bundle.js", + "/node_modules/next/dist/compiled/babel/code-frame.js", + "/node_modules/next/dist/compiled/babel/core.js", + "/node_modules/next/dist/compiled/babel/parser.js", + "/node_modules/next/dist/compiled/babel/traverse.js", + "/node_modules/next/dist/compiled/babel/types.js", + "/node_modules/next/dist/compiled/busboy/index.js", + "/node_modules/next/dist/compiled/bytes/index.js", + "/node_modules/next/dist/compiled/content-disposition/index.js", + "/node_modules/next/dist/compiled/cookie/index.js", + "/node_modules/next/dist/compiled/debug/index.js", + "/node_modules/next/dist/compiled/edge-runtime/index.js", + "/node_modules/next/dist/compiled/fresh/index.js", + "/node_modules/next/dist/compiled/image-detector/detector.js", + "/node_modules/next/dist/compiled/image-size/index.js", + "/node_modules/next/dist/compiled/is-animated/index.js", + "/node_modules/next/dist/compiled/json5/index.js", + "/node_modules/next/dist/compiled/jsonwebtoken/index.js", + "/node_modules/next/dist/compiled/lru-cache/index.js", + "/node_modules/next/dist/compiled/nanoid/index.cjs", + "/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js", + "/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js", + "/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js", + "/node_modules/next/dist/compiled/p-queue/index.js", + "/node_modules/next/dist/compiled/path-browserify/index.js", + "/node_modules/next/dist/compiled/path-to-regexp/index.js", + "/node_modules/next/dist/compiled/picomatch/index.js", + "/node_modules/next/dist/compiled/react-is/cjs/react-is.development.js", + "/node_modules/next/dist/compiled/react-is/cjs/react-is.production.js", + "/node_modules/next/dist/compiled/react-is/index.js", + "/node_modules/next/dist/compiled/semver/index.js", + "/node_modules/next/dist/compiled/send/index.js", + "/node_modules/next/dist/compiled/source-map/source-map.js", + "/node_modules/next/dist/compiled/stacktrace-parser/stack-trace-parser.cjs.js", + "/node_modules/next/dist/compiled/string-hash/index.js", + "/node_modules/next/dist/compiled/strip-ansi/index.js", + "/node_modules/next/dist/compiled/superstruct/index.cjs", + "/node_modules/next/dist/compiled/ws/index.js", + "/node_modules/next/dist/compiled/zod-validation-error/index.js", + "/node_modules/next/dist/compiled/zod/index.cjs", + "/node_modules/next/dist/experimental/testmode/context.js", + "/node_modules/next/dist/experimental/testmode/fetch.js", + "/node_modules/next/dist/experimental/testmode/httpget.js", + "/node_modules/next/dist/experimental/testmode/server-edge.js", + "/node_modules/next/dist/experimental/testmode/server.js", + "/node_modules/next/dist/lib/batcher.js", + "/node_modules/next/dist/lib/client-and-server-references.js", + "/node_modules/next/dist/lib/constants.js", + "/node_modules/next/dist/lib/detached-promise.js", + "/node_modules/next/dist/lib/error-telemetry-utils.js", + "/node_modules/next/dist/lib/fallback.js", + "/node_modules/next/dist/lib/find-pages-dir.js", + "/node_modules/next/dist/lib/format-dynamic-import-path.js", + "/node_modules/next/dist/lib/format-server-error.js", + "/node_modules/next/dist/lib/framework/boundary-components.js", + "/node_modules/next/dist/lib/framework/boundary-constants.js", + "/node_modules/next/dist/lib/generate-interception-routes-rewrites.js", + "/node_modules/next/dist/lib/interop-default.js", + "/node_modules/next/dist/lib/is-api-route.js", + "/node_modules/next/dist/lib/is-app-page-route.js", + "/node_modules/next/dist/lib/is-app-route-route.js", + "/node_modules/next/dist/lib/is-error.js", + "/node_modules/next/dist/lib/is-serializable-props.js", + "/node_modules/next/dist/lib/metadata/get-metadata-route.js", + "/node_modules/next/dist/lib/metadata/is-metadata-route.js", + "/node_modules/next/dist/lib/metadata/metadata-context.js", + "/node_modules/next/dist/lib/multi-file-writer.js", + "/node_modules/next/dist/lib/non-nullable.js", + "/node_modules/next/dist/lib/page-types.js", + "/node_modules/next/dist/lib/pick.js", + "/node_modules/next/dist/lib/picocolors.js", + "/node_modules/next/dist/lib/redirect-status.js", + "/node_modules/next/dist/lib/route-pattern-normalizer.js", + "/node_modules/next/dist/lib/scheduler.js", + "/node_modules/next/dist/lib/semver-noop.js", + "/node_modules/next/dist/lib/static-env.js", + "/node_modules/next/dist/lib/url.js", + "/node_modules/next/dist/lib/wait.js", + "/node_modules/next/dist/next-devtools/server/shared.js", + "/node_modules/next/dist/server/ReactDOMServerPages.js", + "/node_modules/next/dist/server/after/after-context.js", + "/node_modules/next/dist/server/after/awaiter.js", + "/node_modules/next/dist/server/after/builtin-request-context.js", + "/node_modules/next/dist/server/api-utils/get-cookie-parser.js", + "/node_modules/next/dist/server/api-utils/index.js", + "/node_modules/next/dist/server/api-utils/node/try-get-preview-data.js", + "/node_modules/next/dist/server/app-render/action-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/action-async-storage.external.js", + "/node_modules/next/dist/server/app-render/action-handler.js", + "/node_modules/next/dist/server/app-render/action-utils.js", + "/node_modules/next/dist/server/app-render/after-task-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/after-task-async-storage.external.js", + "/node_modules/next/dist/server/app-render/app-render-prerender-utils.js", + "/node_modules/next/dist/server/app-render/app-render-render-utils.js", + "/node_modules/next/dist/server/app-render/app-render.js", + "/node_modules/next/dist/server/app-render/async-local-storage.js", + "/node_modules/next/dist/server/app-render/cache-signal.js", + "/node_modules/next/dist/server/app-render/create-component-styles-and-scripts.js", + "/node_modules/next/dist/server/app-render/create-component-tree.js", + "/node_modules/next/dist/server/app-render/create-error-handler.js", + "/node_modules/next/dist/server/app-render/create-flight-router-state-from-loader-tree.js", + "/node_modules/next/dist/server/app-render/csrf-protection.js", + "/node_modules/next/dist/server/app-render/dynamic-rendering.js", + "/node_modules/next/dist/server/app-render/encryption-utils.js", + "/node_modules/next/dist/server/app-render/flight-render-result.js", + "/node_modules/next/dist/server/app-render/get-asset-query-string.js", + "/node_modules/next/dist/server/app-render/get-css-inlined-link-tags.js", + "/node_modules/next/dist/server/app-render/get-layer-assets.js", + "/node_modules/next/dist/server/app-render/get-preloadable-fonts.js", + "/node_modules/next/dist/server/app-render/get-script-nonce-from-header.js", + "/node_modules/next/dist/server/app-render/get-segment-param.js", + "/node_modules/next/dist/server/app-render/get-short-dynamic-param-type.js", + "/node_modules/next/dist/server/app-render/has-loading-component-in-tree.js", + "/node_modules/next/dist/server/app-render/interop-default.js", + "/node_modules/next/dist/server/app-render/make-get-server-inserted-html.js", + "/node_modules/next/dist/server/app-render/metadata-insertion/create-server-inserted-metadata.js", + "/node_modules/next/dist/server/app-render/module-loading/track-module-loading.external.js", + "/node_modules/next/dist/server/app-render/module-loading/track-module-loading.instance.js", + "/node_modules/next/dist/server/app-render/parse-and-validate-flight-router-state.js", + "/node_modules/next/dist/server/app-render/parse-loader-tree.js", + "/node_modules/next/dist/server/app-render/postponed-state.js", + "/node_modules/next/dist/server/app-render/prospective-render-utils.js", + "/node_modules/next/dist/server/app-render/react-large-shell-error.js", + "/node_modules/next/dist/server/app-render/react-server.node.js", + "/node_modules/next/dist/server/app-render/render-css-resource.js", + "/node_modules/next/dist/server/app-render/required-scripts.js", + "/node_modules/next/dist/server/app-render/segment-explorer-path.js", + "/node_modules/next/dist/server/app-render/server-inserted-html.js", + "/node_modules/next/dist/server/app-render/strip-flight-headers.js", + "/node_modules/next/dist/server/app-render/types.js", + "/node_modules/next/dist/server/app-render/use-flight-response.js", + "/node_modules/next/dist/server/app-render/walk-tree-with-flight-router-state.js", + "/node_modules/next/dist/server/app-render/work-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/work-async-storage.external.js", + "/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/work-unit-async-storage.external.js", + "/node_modules/next/dist/server/async-storage/draft-mode-provider.js", + "/node_modules/next/dist/server/async-storage/request-store.js", + "/node_modules/next/dist/server/async-storage/work-store.js", + "/node_modules/next/dist/server/base-http/helpers.js", + "/node_modules/next/dist/server/base-http/index.js", + "/node_modules/next/dist/server/base-http/node.js", + "/node_modules/next/dist/server/base-server.js", + "/node_modules/next/dist/server/body-streams.js", + "/node_modules/next/dist/server/client-component-renderer-logger.js", + "/node_modules/next/dist/server/crypto-utils.js", + "/node_modules/next/dist/server/dev/node-stack-frames.js", + "/node_modules/next/dist/server/dynamic-rendering-utils.js", + "/node_modules/next/dist/server/htmlescape.js", + "/node_modules/next/dist/server/image-optimizer.js", + "/node_modules/next/dist/server/instrumentation/utils.js", + "/node_modules/next/dist/server/internal-utils.js", + "/node_modules/next/dist/server/lib/app-dir-module.js", + "/node_modules/next/dist/server/lib/async-callback-set.js", + "/node_modules/next/dist/server/lib/cache-control.js", + "/node_modules/next/dist/server/lib/cache-handlers/default.external.js", + "/node_modules/next/dist/server/lib/clone-response.js", + "/node_modules/next/dist/server/lib/decode-query-path-parameter.js", + "/node_modules/next/dist/server/lib/dedupe-fetch.js", + "/node_modules/next/dist/server/lib/etag.js", + "/node_modules/next/dist/server/lib/experimental/ppr.js", + "/node_modules/next/dist/server/lib/fix-mojibake.js", + "/node_modules/next/dist/server/lib/format-hostname.js", + "/node_modules/next/dist/server/lib/i18n-provider.js", + "/node_modules/next/dist/server/lib/implicit-tags.js", + "/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js", + "/node_modules/next/dist/server/lib/incremental-cache/index.js", + "/node_modules/next/dist/server/lib/incremental-cache/memory-cache.external.js", + "/node_modules/next/dist/server/lib/incremental-cache/shared-cache-controls.external.js", + "/node_modules/next/dist/server/lib/incremental-cache/tags-manifest.external.js", + "/node_modules/next/dist/server/lib/is-ipv6.js", + "/node_modules/next/dist/server/lib/lazy-result.js", + "/node_modules/next/dist/server/lib/lru-cache.js", + "/node_modules/next/dist/server/lib/match-next-data-pathname.js", + "/node_modules/next/dist/server/lib/mock-request.js", + "/node_modules/next/dist/server/lib/module-loader/node-module-loader.js", + "/node_modules/next/dist/server/lib/node-fs-methods.js", + "/node_modules/next/dist/server/lib/parse-stack.js", + "/node_modules/next/dist/server/lib/patch-fetch.js", + "/node_modules/next/dist/server/lib/patch-set-header.js", + "/node_modules/next/dist/server/lib/router-utils/decode-path-params.js", + "/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js", + "/node_modules/next/dist/server/lib/router-utils/instrumentation-node-extensions.js", + "/node_modules/next/dist/server/lib/router-utils/is-postpone.js", + "/node_modules/next/dist/server/lib/router-utils/router-server-context.js", + "/node_modules/next/dist/server/lib/server-action-request-meta.js", + "/node_modules/next/dist/server/lib/server-ipc/utils.js", + "/node_modules/next/dist/server/lib/source-maps.js", + "/node_modules/next/dist/server/lib/streaming-metadata.js", + "/node_modules/next/dist/server/lib/to-route.js", + "/node_modules/next/dist/server/lib/trace/constants.js", + "/node_modules/next/dist/server/lib/trace/tracer.js", + "/node_modules/next/dist/server/lib/trace/utils.js", + "/node_modules/next/dist/server/load-components.js", + "/node_modules/next/dist/server/load-manifest.external.js", + "/node_modules/next/dist/server/next-server.js", + "/node_modules/next/dist/server/node-environment-baseline.js", + "/node_modules/next/dist/server/node-environment-extensions/console-dev.js", + "/node_modules/next/dist/server/node-environment-extensions/date.js", + "/node_modules/next/dist/server/node-environment-extensions/error-inspect.js", + "/node_modules/next/dist/server/node-environment-extensions/node-crypto.js", + "/node_modules/next/dist/server/node-environment-extensions/random.js", + "/node_modules/next/dist/server/node-environment-extensions/utils.js", + "/node_modules/next/dist/server/node-environment-extensions/web-crypto.js", + "/node_modules/next/dist/server/node-environment.js", + "/node_modules/next/dist/server/node-polyfill-crypto.js", + "/node_modules/next/dist/server/normalizers/absolute-filename-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/app/app-bundle-path-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/app/app-filename-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/app/app-page-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/app/app-pathname-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/app/index.js", + "/node_modules/next/dist/server/normalizers/built/pages/index.js", + "/node_modules/next/dist/server/normalizers/built/pages/pages-bundle-path-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/pages/pages-filename-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/pages/pages-page-normalizer.js", + "/node_modules/next/dist/server/normalizers/built/pages/pages-pathname-normalizer.js", + "/node_modules/next/dist/server/normalizers/locale-route-normalizer.js", + "/node_modules/next/dist/server/normalizers/normalizers.js", + "/node_modules/next/dist/server/normalizers/prefixing-normalizer.js", + "/node_modules/next/dist/server/normalizers/request/next-data.js", + "/node_modules/next/dist/server/normalizers/request/prefetch-rsc.js", + "/node_modules/next/dist/server/normalizers/request/prefix.js", + "/node_modules/next/dist/server/normalizers/request/rsc.js", + "/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.js", + "/node_modules/next/dist/server/normalizers/request/suffix.js", + "/node_modules/next/dist/server/normalizers/underscore-normalizer.js", + "/node_modules/next/dist/server/normalizers/wrap-normalizer-fn.js", + "/node_modules/next/dist/server/patch-error-inspect.js", + "/node_modules/next/dist/server/pipe-readable.js", + "/node_modules/next/dist/server/post-process.js", + "/node_modules/next/dist/server/render-result.js", + "/node_modules/next/dist/server/render.js", + "/node_modules/next/dist/server/request-meta.js", + "/node_modules/next/dist/server/request/fallback-params.js", + "/node_modules/next/dist/server/require-hook.js", + "/node_modules/next/dist/server/require.js", + "/node_modules/next/dist/server/response-cache/index.js", + "/node_modules/next/dist/server/response-cache/types.js", + "/node_modules/next/dist/server/response-cache/utils.js", + "/node_modules/next/dist/server/resume-data-cache/cache-store.js", + "/node_modules/next/dist/server/resume-data-cache/resume-data-cache.js", + "/node_modules/next/dist/server/revalidation-utils.js", + "/node_modules/next/dist/server/route-kind.js", + "/node_modules/next/dist/server/route-matcher-managers/default-route-matcher-manager.js", + "/node_modules/next/dist/server/route-matcher-providers/app-page-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matcher-providers/app-route-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matcher-providers/helpers/cached-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matcher-providers/helpers/manifest-loaders/server-manifest-loader.js", + "/node_modules/next/dist/server/route-matcher-providers/manifest-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matcher-providers/pages-api-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matcher-providers/pages-route-matcher-provider.js", + "/node_modules/next/dist/server/route-matchers/app-page-route-matcher.js", + "/node_modules/next/dist/server/route-matchers/app-route-route-matcher.js", + "/node_modules/next/dist/server/route-matchers/locale-route-matcher.js", + "/node_modules/next/dist/server/route-matchers/pages-api-route-matcher.js", + "/node_modules/next/dist/server/route-matchers/pages-route-matcher.js", + "/node_modules/next/dist/server/route-matchers/route-matcher.js", + "/node_modules/next/dist/server/route-matches/pages-api-route-match.js", + "/node_modules/next/dist/server/route-modules/app-page/helpers/prerender-manifest-matcher.js", + "/node_modules/next/dist/server/route-modules/app-page/module.compiled.js", + "/node_modules/next/dist/server/route-modules/app-page/module.js", + "/node_modules/next/dist/server/route-modules/app-page/module.render.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/amp-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/app-router-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/head-manager-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/hooks-client-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/image-config-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/router-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/server-inserted-html.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.js", + "/node_modules/next/dist/server/route-modules/checks.js", + "/node_modules/next/dist/server/route-modules/pages/module.compiled.js", + "/node_modules/next/dist/server/route-modules/pages/module.js", + "/node_modules/next/dist/server/route-modules/pages/module.render.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/amp-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/app-router-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/head-manager-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/hooks-client-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/html-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/image-config-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/router-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/server-inserted-html.js", + "/node_modules/next/dist/server/route-modules/route-module.js", + "/node_modules/next/dist/server/send-payload.js", + "/node_modules/next/dist/server/send-response.js", + "/node_modules/next/dist/server/serve-static.js", + "/node_modules/next/dist/server/server-utils.js", + "/node_modules/next/dist/server/setup-http-agent-env.js", + "/node_modules/next/dist/server/stream-utils/encoded-tags.js", + "/node_modules/next/dist/server/stream-utils/node-web-streams-helper.js", + "/node_modules/next/dist/server/stream-utils/uint8array-helpers.js", + "/node_modules/next/dist/server/use-cache/handlers.js", + "/node_modules/next/dist/server/utils.js", + "/node_modules/next/dist/server/web/adapter.js", + "/node_modules/next/dist/server/web/error.js", + "/node_modules/next/dist/server/web/get-edge-preview-props.js", + "/node_modules/next/dist/server/web/globals.js", + "/node_modules/next/dist/server/web/next-url.js", + "/node_modules/next/dist/server/web/sandbox/context.js", + "/node_modules/next/dist/server/web/sandbox/fetch-inline-assets.js", + "/node_modules/next/dist/server/web/sandbox/index.js", + "/node_modules/next/dist/server/web/sandbox/resource-managers.js", + "/node_modules/next/dist/server/web/sandbox/sandbox.js", + "/node_modules/next/dist/server/web/spec-extension/adapters/headers.js", + "/node_modules/next/dist/server/web/spec-extension/adapters/next-request.js", + "/node_modules/next/dist/server/web/spec-extension/adapters/reflect.js", + "/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.js", + "/node_modules/next/dist/server/web/spec-extension/cookies.js", + "/node_modules/next/dist/server/web/spec-extension/fetch-event.js", + "/node_modules/next/dist/server/web/spec-extension/request.js", + "/node_modules/next/dist/server/web/spec-extension/response.js", + "/node_modules/next/dist/server/web/utils.js", + "/node_modules/next/dist/server/web/web-on-close.js", + "/node_modules/next/dist/shared/lib/amp-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/amp-mode.js", + "/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/app-router-types.js", + "/node_modules/next/dist/shared/lib/constants.js", + "/node_modules/next/dist/shared/lib/deep-freeze.js", + "/node_modules/next/dist/shared/lib/encode-uri-path.js", + "/node_modules/next/dist/shared/lib/entry-constants.js", + "/node_modules/next/dist/shared/lib/error-source.js", + "/node_modules/next/dist/shared/lib/errors/constants.js", + "/node_modules/next/dist/shared/lib/escape-regexp.js", + "/node_modules/next/dist/shared/lib/get-hostname.js", + "/node_modules/next/dist/shared/lib/hash.js", + "/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/head.js", + "/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/html-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/i18n/detect-domain-locale.js", + "/node_modules/next/dist/shared/lib/i18n/normalize-locale-path.js", + "/node_modules/next/dist/shared/lib/image-blur-svg.js", + "/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/image-config.js", + "/node_modules/next/dist/shared/lib/invariant-error.js", + "/node_modules/next/dist/shared/lib/is-internal.js", + "/node_modules/next/dist/shared/lib/is-plain-object.js", + "/node_modules/next/dist/shared/lib/is-thenable.js", + "/node_modules/next/dist/shared/lib/isomorphic/path.js", + "/node_modules/next/dist/shared/lib/lazy-dynamic/bailout-to-csr.js", + "/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/loadable.shared-runtime.js", + "/node_modules/next/dist/shared/lib/match-local-pattern.js", + "/node_modules/next/dist/shared/lib/match-remote-pattern.js", + "/node_modules/next/dist/shared/lib/modern-browserslist-target.js", + "/node_modules/next/dist/shared/lib/no-fallback-error.external.js", + "/node_modules/next/dist/shared/lib/page-path/absolute-path-to-page.js", + "/node_modules/next/dist/shared/lib/page-path/denormalize-page-path.js", + "/node_modules/next/dist/shared/lib/page-path/ensure-leading-slash.js", + "/node_modules/next/dist/shared/lib/page-path/normalize-data-path.js", + "/node_modules/next/dist/shared/lib/page-path/normalize-page-path.js", + "/node_modules/next/dist/shared/lib/page-path/normalize-path-sep.js", + "/node_modules/next/dist/shared/lib/page-path/remove-page-path-tail.js", + "/node_modules/next/dist/shared/lib/promise-with-resolvers.js", + "/node_modules/next/dist/shared/lib/router-context.shared-runtime.js", + "/node_modules/next/dist/shared/lib/router/adapters.js", + "/node_modules/next/dist/shared/lib/router/utils/add-locale.js", + "/node_modules/next/dist/shared/lib/router/utils/add-path-prefix.js", + "/node_modules/next/dist/shared/lib/router/utils/add-path-suffix.js", + "/node_modules/next/dist/shared/lib/router/utils/app-paths.js", + "/node_modules/next/dist/shared/lib/router/utils/as-path-to-search-params.js", + "/node_modules/next/dist/shared/lib/router/utils/cache-busting-search-param.js", + "/node_modules/next/dist/shared/lib/router/utils/escape-path-delimiters.js", + "/node_modules/next/dist/shared/lib/router/utils/format-next-pathname-info.js", + "/node_modules/next/dist/shared/lib/router/utils/format-url.js", + "/node_modules/next/dist/shared/lib/router/utils/get-dynamic-param.js", + "/node_modules/next/dist/shared/lib/router/utils/get-next-pathname-info.js", + "/node_modules/next/dist/shared/lib/router/utils/get-route-from-asset-path.js", + "/node_modules/next/dist/shared/lib/router/utils/html-bots.js", + "/node_modules/next/dist/shared/lib/router/utils/index.js", + "/node_modules/next/dist/shared/lib/router/utils/interception-routes.js", + "/node_modules/next/dist/shared/lib/router/utils/is-bot.js", + "/node_modules/next/dist/shared/lib/router/utils/is-dynamic.js", + "/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.js", + "/node_modules/next/dist/shared/lib/router/utils/parse-path.js", + "/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.js", + "/node_modules/next/dist/shared/lib/router/utils/parse-url.js", + "/node_modules/next/dist/shared/lib/router/utils/path-has-prefix.js", + "/node_modules/next/dist/shared/lib/router/utils/path-match.js", + "/node_modules/next/dist/shared/lib/router/utils/prepare-destination.js", + "/node_modules/next/dist/shared/lib/router/utils/querystring.js", + "/node_modules/next/dist/shared/lib/router/utils/relativize-url.js", + "/node_modules/next/dist/shared/lib/router/utils/remove-path-prefix.js", + "/node_modules/next/dist/shared/lib/router/utils/remove-trailing-slash.js", + "/node_modules/next/dist/shared/lib/router/utils/route-match-utils.js", + "/node_modules/next/dist/shared/lib/router/utils/route-matcher.js", + "/node_modules/next/dist/shared/lib/router/utils/route-regex.js", + "/node_modules/next/dist/shared/lib/router/utils/sorted-routes.js", + "/node_modules/next/dist/shared/lib/runtime-config.external.js", + "/node_modules/next/dist/shared/lib/segment-cache/output-export-prefetch-encoding.js", + "/node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.js", + "/node_modules/next/dist/shared/lib/segment.js", + "/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.js", + "/node_modules/next/dist/shared/lib/server-reference-info.js", + "/node_modules/next/dist/shared/lib/side-effect.js", + "/node_modules/next/dist/shared/lib/utils.js", + "/node_modules/next/dist/shared/lib/utils/warn-once.js", + "/node_modules/next/dist/shared/lib/zod.js", + "/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js", + "/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js", + "/node_modules/react-dom/cjs/react-dom-server.browser.production.js", + "/node_modules/react-dom/cjs/react-dom-server.edge.production.js", + "/node_modules/react-dom/cjs/react-dom-server.node.production.js", + "/node_modules/react-dom/cjs/react-dom.production.js", + "/node_modules/react-dom/index.js", + "/node_modules/react-dom/server.browser.js", + "/node_modules/react-dom/server.edge.js", + "/node_modules/react-dom/server.node.js", + "/node_modules/react-dom/static.node.js", + "/node_modules/react/cjs/react-compiler-runtime.production.js", + "/node_modules/react/cjs/react-jsx-dev-runtime.production.js", + "/node_modules/react/cjs/react-jsx-runtime.production.js", + "/node_modules/react/cjs/react.production.js", + "/node_modules/react/compiler-runtime.js", + "/node_modules/react/index.js", + "/node_modules/react/jsx-dev-runtime.js", + "/node_modules/react/jsx-runtime.js", + "/node_modules/semver/classes/comparator.js", + "/node_modules/semver/classes/range.js", + "/node_modules/semver/classes/semver.js", + "/node_modules/semver/functions/cmp.js", + "/node_modules/semver/functions/coerce.js", + "/node_modules/semver/functions/compare.js", + "/node_modules/semver/functions/eq.js", + "/node_modules/semver/functions/gt.js", + "/node_modules/semver/functions/gte.js", + "/node_modules/semver/functions/lt.js", + "/node_modules/semver/functions/lte.js", + "/node_modules/semver/functions/neq.js", + "/node_modules/semver/functions/parse.js", + "/node_modules/semver/functions/satisfies.js", + "/node_modules/semver/internal/constants.js", + "/node_modules/semver/internal/debug.js", + "/node_modules/semver/internal/identifiers.js", + "/node_modules/semver/internal/lrucache.js", + "/node_modules/semver/internal/parse-options.js", + "/node_modules/semver/internal/re.js", + "/node_modules/sharp/lib/channel.js", + "/node_modules/sharp/lib/colour.js", + "/node_modules/sharp/lib/composite.js", + "/node_modules/sharp/lib/constructor.js", + "/node_modules/sharp/lib/index.js", + "/node_modules/sharp/lib/input.js", + "/node_modules/sharp/lib/is.js", + "/node_modules/sharp/lib/libvips.js", + "/node_modules/sharp/lib/operation.js", + "/node_modules/sharp/lib/output.js", + "/node_modules/sharp/lib/resize.js", + "/node_modules/sharp/lib/sharp.js", + "/node_modules/sharp/lib/utility.js", + "/node_modules/simple-swizzle/index.js", + "/node_modules/styled-jsx/dist/index/index.js", + "/node_modules/styled-jsx/index.js", + "/node_modules/styled-jsx/style.js", + "@img/sharp-*/sharp-*.node", + "@img/sharp-libvips-*", + ] + `) + }) + + it('should not trace too many files in next-minimal-server.js.nft.json', async () => { + let trace = await readNormalizedNFT( + '.next/next-minimal-server.js.nft.json' + ) + expect(trace).toMatchInlineSnapshot(` + [ + "/node_modules/client-only/index.js", + "/node_modules/next/dist/client/components/app-router-headers.js", + "/node_modules/next/dist/compiled/@opentelemetry/api/index.js", + "/node_modules/next/dist/compiled/babel-packages/packages-bundle.js", + "/node_modules/next/dist/compiled/babel/bundle.js", + "/node_modules/next/dist/compiled/babel/code-frame.js", + "/node_modules/next/dist/compiled/babel/core.js", + "/node_modules/next/dist/compiled/babel/parser.js", + "/node_modules/next/dist/compiled/babel/traverse.js", + "/node_modules/next/dist/compiled/babel/types.js", + "/node_modules/next/dist/compiled/debug/index.js", + "/node_modules/next/dist/compiled/json5/index.js", + "/node_modules/next/dist/compiled/lru-cache/index.js", + "/node_modules/next/dist/compiled/next-server/server.runtime.prod.js", + "/node_modules/next/dist/compiled/semver/index.js", + "/node_modules/next/dist/compiled/source-map/source-map.js", + "/node_modules/next/dist/compiled/stacktrace-parser/stack-trace-parser.cjs.js", + "/node_modules/next/dist/compiled/ws/index.js", + "/node_modules/next/dist/experimental/testmode/context.js", + "/node_modules/next/dist/experimental/testmode/fetch.js", + "/node_modules/next/dist/experimental/testmode/server-edge.js", + "/node_modules/next/dist/lib/client-and-server-references.js", + "/node_modules/next/dist/lib/constants.js", + "/node_modules/next/dist/lib/interop-default.js", + "/node_modules/next/dist/lib/is-error.js", + "/node_modules/next/dist/server/app-render/after-task-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/after-task-async-storage.external.js", + "/node_modules/next/dist/server/app-render/async-local-storage.js", + "/node_modules/next/dist/server/app-render/work-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/work-async-storage.external.js", + "/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.js", + "/node_modules/next/dist/server/app-render/work-unit-async-storage.external.js", + "/node_modules/next/dist/server/lib/cache-handlers/default.external.js", + "/node_modules/next/dist/server/lib/incremental-cache/memory-cache.external.js", + "/node_modules/next/dist/server/lib/incremental-cache/shared-cache-controls.external.js", + "/node_modules/next/dist/server/lib/incremental-cache/tags-manifest.external.js", + "/node_modules/next/dist/server/lib/lru-cache.js", + "/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js", + "/node_modules/next/dist/server/lib/router-utils/instrumentation-node-extensions.js", + "/node_modules/next/dist/server/lib/trace/constants.js", + "/node_modules/next/dist/server/lib/trace/tracer.js", + "/node_modules/next/dist/server/load-manifest.external.js", + "/node_modules/next/dist/server/response-cache/types.js", + "/node_modules/next/dist/server/route-modules/app-page/module.compiled.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/amp-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/app-router-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/head-manager-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/hooks-client-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/image-config-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/router-context.js", + "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/server-inserted-html.js", + "/node_modules/next/dist/server/route-modules/pages/module.compiled.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/amp-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/app-router-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/head-manager-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/hooks-client-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/html-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/image-config-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/router-context.js", + "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/server-inserted-html.js", + "/node_modules/next/dist/shared/lib/deep-freeze.js", + "/node_modules/next/dist/shared/lib/invariant-error.js", + "/node_modules/next/dist/shared/lib/is-plain-object.js", + "/node_modules/next/dist/shared/lib/is-thenable.js", + "/node_modules/next/dist/shared/lib/no-fallback-error.external.js", + "/node_modules/next/dist/shared/lib/runtime-config.external.js", + "/node_modules/next/dist/shared/lib/server-reference-info.js", + "/node_modules/react/cjs/react.production.js", + "/node_modules/react/index.js", + "/node_modules/styled-jsx/dist/index/index.js", + "/node_modules/styled-jsx/index.js", + "/node_modules/styled-jsx/style.js", + ] + `) + }) + } +) diff --git a/test/production/next-server-nft/next.config.js b/test/production/next-server-nft/next.config.js new file mode 100644 index 00000000000000..807126e4cf0bf5 --- /dev/null +++ b/test/production/next-server-nft/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 20ff3c6eabc3736854448e695b5fcc5e9d54fc85 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:23:35 +0200 Subject: [PATCH 07/10] Remove Collecting build traces JS step --- packages/next/src/build/collect-build-traces.ts | 13 ++----------- packages/next/src/build/index.ts | 9 +++++---- .../build-output-tree-view.test.ts | 8 ++++---- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/next/src/build/collect-build-traces.ts b/packages/next/src/build/collect-build-traces.ts index ef8c9ce4bb80f6..4f9efd7fa51d6b 100644 --- a/packages/next/src/build/collect-build-traces.ts +++ b/packages/next/src/build/collect-build-traces.ts @@ -82,7 +82,6 @@ export async function collectBuildTraces({ hasSsrAmpPages, buildTraceContext, outputFileTracingRoot, - isTurbopack, }: { dir: string distDir: string @@ -94,7 +93,6 @@ export async function collectBuildTraces({ nextBuildSpan?: Span config: NextConfigComplete buildTraceContext?: BuildTraceContext - isTurbopack: boolean }) { const startTime = Date.now() debug('starting build traces') @@ -111,13 +109,11 @@ export async function collectBuildTraces({ .traceAsyncFn(async () => { const nextServerTraceOutput = path.join( distDir, - isTurbopack ? 'next-server.ref.js.nft.json' : 'next-server.js.nft.json' + 'next-server.js.nft.json' ) const nextMinimalTraceOutput = path.join( distDir, - isTurbopack - ? 'next-minimal-server.ref.js.nft.json' - : 'next-minimal-server.js.nft.json' + 'next-minimal-server.js.nft.json' ) const root = outputFileTracingRoot @@ -282,11 +278,6 @@ export async function collectBuildTraces({ ) } - if (isTurbopack) { - addToTracedFiles(distDir, './package.json', serverTracedFiles) - addToTracedFiles(distDir, './package.json', minimalServerTracedFiles) - } - { const chunksToTrace: string[] = [ ...(buildTraceContext?.chunksTrace?.action.input || []), diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 400782a683f9e6..77122300b9549d 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -1748,7 +1748,6 @@ export default async function build( hasSsrAmpPages: false, buildTraceContext, outputFileTracingRoot, - isTurbopack: false, }) .catch((err) => { console.error(err) @@ -2642,7 +2641,7 @@ export default async function build( await writeFunctionsConfigManifest(distDir, functionsConfigManifest) - if (!isGenerateMode && !buildTracesPromise) { + if (!isTurbopack && !isGenerateMode && !buildTracesPromise) { buildTracesPromise = collectBuildTraces({ dir, config, @@ -2653,7 +2652,6 @@ export default async function build( hasSsrAmpPages, buildTraceContext, outputFileTracingRoot, - isTurbopack, }).catch((err) => { console.error(err) process.exit(1) @@ -3935,7 +3933,10 @@ export default async function build( } const postBuildSpinner = createSpinner('Finalizing page optimization') - let buildTracesSpinner = createSpinner(`Collecting build traces`) + let buildTracesSpinner + if (buildTracesPromise) { + buildTracesSpinner = createSpinner('Collecting build traces') + } // ensure the worker is not left hanging worker.end() diff --git a/test/production/app-dir/build-output-tree-view/build-output-tree-view.test.ts b/test/production/app-dir/build-output-tree-view/build-output-tree-view.test.ts index 0e6bcc425fdc05..60a985c9b583c5 100644 --- a/test/production/app-dir/build-output-tree-view/build-output-tree-view.test.ts +++ b/test/production/app-dir/build-output-tree-view/build-output-tree-view.test.ts @@ -74,15 +74,15 @@ describe('build-output-tree-view', () => { }) function getTreeView(cliOutput: string): string { - let foundBuildTracesLine = false + let foundStart = false const lines: string[] = [] for (const line of cliOutput.split('\n')) { - if (foundBuildTracesLine) { + foundStart ||= line.startsWith('Route ') + + if (foundStart) { lines.push(line) } - - foundBuildTracesLine ||= line.includes('Collecting build traces') } return lines.join('\n').trim() From ffc427738d71b6520d9dd5a2b6b58be00da8f1a8 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:43:22 +0200 Subject: [PATCH 08/10] review feedback --- crates/next-api/src/next_server_nft.rs | 38 ++++++++++++-------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/crates/next-api/src/next_server_nft.rs b/crates/next-api/src/next_server_nft.rs index 574e28586b6a7a..d741753fe88ef7 100644 --- a/crates/next-api/src/next_server_nft.rs +++ b/crates/next-api/src/next_server_nft.rs @@ -156,34 +156,30 @@ pub async fn next_server_nft_assets(project: Vc) -> Result>(); From 164e370f0cbe0c0efb84bebd4c9b4c3aad1db0c1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 29 Aug 2025 16:43:19 +0200 Subject: [PATCH 09/10] feedback: refactor to be more lazy --- crates/next-api/src/next_server_nft.rs | 466 +++++++++++++------------ crates/next-api/src/nft_json.rs | 5 +- 2 files changed, 246 insertions(+), 225 deletions(-) diff --git a/crates/next-api/src/next_server_nft.rs b/crates/next-api/src/next_server_nft.rs index d741753fe88ef7..f31e0534446df9 100644 --- a/crates/next-api/src/next_server_nft.rs +++ b/crates/next-api/src/next_server_nft.rs @@ -3,17 +3,19 @@ use std::collections::BTreeSet; use anyhow::{Context, Result, bail}; use either::Either; use next_core::{get_next_package, next_server::get_tracing_compile_time_info}; +use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; -use tracing::{Level, instrument}; use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, Vc}; +use turbo_tasks::{ + NonLocalValue, ResolvedVc, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, Vc, + trace::TraceRawVcs, +}; use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, File, FileSystemPath, glob::Glob}; use turbopack::externals_tracing_module_context; use turbopack_core::{ asset::{Asset, AssetContent}, context::AssetContext, file_source::FileSource, - module::Module, output::{OutputAsset, OutputAssets}, reference_type::{CommonJsReferenceSubType, ReferenceType}, resolve::{ExternalType, origin::PlainResolveOrigin, parse::Request}, @@ -21,204 +23,31 @@ use turbopack_core::{ }; use turbopack_ecmascript::resolve::cjs_resolve; -use crate::{nft_json::all_assets_from_entries_filtered, project::Project}; +use crate::{ + nft_json::{all_assets_from_entries_filtered, relativize_glob}, + project::Project, +}; + +#[derive( + PartialEq, Eq, TraceRawVcs, NonLocalValue, Deserialize, Serialize, Debug, Clone, Hash, TaskInput, +)] +enum ServerNftType { + Minimal, + Full, +} -#[instrument(level = Level::INFO, skip_all)] #[turbo_tasks::function] pub async fn next_server_nft_assets(project: Vc) -> Result> { - let is_standalone = *project.next_config().is_standalone().await?; - let has_next_support = *project.next_config().ci_has_next_support().await?; - - let asset_context = Vc::upcast(externals_tracing_module_context( - ExternalType::CommonJs, - get_tracing_compile_time_info(), - )); - - let project_path = project.project_path().owned().await?; - - let next_resolve_origin = Vc::upcast(PlainResolveOrigin::new( - asset_context, - get_next_package(project_path.clone()).await?.join("_")?, - )); - - let resolve_entry = async |path: &str| { - Ok(cjs_resolve( - next_resolve_origin, - Request::parse_string(path.into()), - CommonJsReferenceSubType::Undefined, - None, - false, - ) - .primary_modules() - .await? - .into_iter() - .map(|m| **m)) - }; - - let cache_handler = project - .next_config() - .cache_handler(project_path.clone()) - .await?; - let cache_handlers = project - .next_config() - .experimental_cache_handlers(project_path.clone()) - .await?; - - // These are used by packages/next/src/server/require-hook.ts - let shared_entries: Vec>> = - ["styled-jsx", "styled-jsx/style", "styled-jsx/style.js"] - .into_iter() - .map(resolve_entry) - .try_flat_join() - .await?; - - let cache_handler_entries: Vec>> = cache_handler - .into_iter() - .chain(cache_handlers.into_iter()) - .map(|f| { - asset_context - .process( - Vc::upcast(FileSource::new(f.clone())), - ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined), - ) - .module() - }) - .collect(); - - let server_entries = shared_entries - .iter() - .chain(cache_handler_entries.iter()) - .copied() - .chain(if is_standalone { - Either::Left( - resolve_entry("next/dist/server/lib/start-server") - .await? - .chain(resolve_entry("next/dist/server/next").await?) - .chain(resolve_entry("next/dist/server/require-hook").await?), - ) - } else { - Either::Right(std::iter::empty()) - }) - .chain(resolve_entry("next/dist/server/next-server").await?) - .map(|m| Vc::upcast::>(TracedAsset::new(m)).to_resolved()) - .try_join() - .await?; - - let minimal_server_entries = shared_entries - .iter() - .chain(cache_handler_entries.iter()) - .copied() - .chain(resolve_entry("next/dist/compiled/next-server/server.runtime.prod").await?) - .map(|m| Vc::upcast::>(TracedAsset::new(m)).to_resolved()) - .try_join() - .await?; - - let output_file_tracing_excludes = project.next_config().output_file_tracing_excludes().await?; - let mut additional_ignores = BTreeSet::new(); - if let Some(output_file_tracing_excludes) = output_file_tracing_excludes - .as_ref() - .and_then(Value::as_object) - { - for (glob_pattern, exclude_patterns) in output_file_tracing_excludes { - // Check if the route matches the glob pattern - let glob = Glob::new(RcStr::from(glob_pattern.clone()), Default::default()).await?; - if glob.matches("next-server") - && let Some(patterns) = exclude_patterns.as_array() - { - for pattern in patterns { - if let Some(pattern_str) = pattern.as_str() { - additional_ignores.insert(pattern_str); - } - } - } - } - } - - let server_ignores_glob = [ - "**/node_modules/react{,-dom,-server-dom-turbopack}/**/*.development.js", - "**/*.d.ts", - "**/*.map", - "**/next/dist/pages/**/*", - "**/next/dist/compiled/next-server/**/*.dev.js", - "**/next/dist/compiled/webpack/*", - "**/node_modules/webpack5/**/*", - "**/next/dist/server/lib/route-resolver*", - "**/next/dist/compiled/semver/semver/**/*.js", - "**/next/dist/compiled/jest-worker/**/*", - // Turbopack doesn't support AMP - "**/next/dist/compiled/@ampproject/toolbox-optimizer/**/*", - // -- The following were added for Turbopack specifically -- - // client/components/use-action-queue.ts has a process.env.NODE_ENV guard, but we can't set that due to React: https://github.com/vercel/next.js/pull/75254 - "**/next/dist/next-devtools/userspace/use-app-dev-rendering-indicator.js", - // client/components/app-router.js has a process.env.NODE_ENV guard, but we can't set that. - "**/next/dist/client/dev/hot-reloader/app/hot-reloader-app.js", - // server/lib/router-server.js doesn't guard this require: - "**/next/dist/server/lib/router-utils/setup-dev-bundler.js", - // server/next.js doesn't guard this require - "**/next/dist/server/dev/next-dev-server.js", - // next/dist/compiled/babel* pulls in this, but we never actually transpile at deploy-time - "**/next/dist/compiled/browserslist/**", - ] - .into_iter() - .chain(additional_ignores) - // only ignore image-optimizer code when - // this is being handled outside of next-server - .chain(if has_next_support { - Either::Left( - [ - "**/node_modules/sharp/**/*", - "**/@img/sharp-libvips*/**/*", - "**/next/dist/server/image-optimizer.js", - ] - .into_iter(), - ) - } else { - Either::Right(std::iter::empty()) - }) - .chain(if is_standalone { - Either::Left(std::iter::empty()) - } else { - Either::Right(["**/*/next/dist/server/next.js", "**/*/next/dist/bin/next"].into_iter()) - }) - .map(|g| Glob::new(g.into(), Default::default())) - .collect::>(); - - let minimal_server_ignores_glob = Glob::alternatives( - server_ignores_glob - .iter() - .copied() - .chain( - [ - "**/next/dist/compiled/edge-runtime/**/*", - "**/next/dist/server/web/sandbox/**/*", - "**/next/dist/server/post-process.js", - ] - .into_iter() - .map(|g| Glob::new(g.into(), Default::default())), - ) - .collect(), - ); - Ok(Vc::cell(vec![ ResolvedVc::upcast( - ServerNftJsonAsset::new( - project, - RcStr::from("next-server"), - Vc::cell(server_entries), - Glob::alternatives(server_ignores_glob), - ) - .to_resolved() - .await?, + ServerNftJsonAsset::new(project, ServerNftType::Full) + .to_resolved() + .await?, ), ResolvedVc::upcast( - ServerNftJsonAsset::new( - project, - RcStr::from("next-minimal-server"), - Vc::cell(minimal_server_entries), - minimal_server_ignores_glob, - ) - .to_resolved() - .await?, + ServerNftJsonAsset::new(project, ServerNftType::Minimal) + .to_resolved() + .await?, ), ])) } @@ -226,27 +55,14 @@ pub async fn next_server_nft_assets(project: Vc) -> Result, - name: RcStr, - entries: ResolvedVc, - ignores: ResolvedVc, + ty: ServerNftType, } #[turbo_tasks::value_impl] impl ServerNftJsonAsset { #[turbo_tasks::function] - pub fn new( - project: ResolvedVc, - name: RcStr, - entries: ResolvedVc, - ignores: ResolvedVc, - ) -> Vc { - ServerNftJsonAsset { - project, - name, - entries, - ignores, - } - .cell() + pub fn new(project: ResolvedVc, ty: ServerNftType) -> Vc { + ServerNftJsonAsset { project, ty }.cell() } } @@ -254,34 +70,35 @@ impl ServerNftJsonAsset { impl OutputAsset for ServerNftJsonAsset { #[turbo_tasks::function] async fn path(&self) -> Result> { - Ok(self - .project - .node_root() - .await? - .join(&format!("{}.js.nft.json", self.name))? - .cell()) + let name = match self.ty { + ServerNftType::Minimal => "next-minimal-server.js.nft.json", + ServerNftType::Full => "next-server.js.nft.json", + }; + + Ok(self.project.node_root().await?.join(name)?.cell()) } } #[turbo_tasks::value_impl] impl Asset for ServerNftJsonAsset { #[turbo_tasks::function] - async fn content(&self) -> Result> { + async fn content(self: Vc) -> Result> { + let this = self.await?; // Example: [project]/apps/my-website/.next/ - let base_dir = self + let base_dir = this .project .project_root_path() .await? - .join(&self.project.node_root().await?.path)?; + .join(&this.project.node_root().await?.path)?; let mut server_output_assets = - all_assets_from_entries_filtered(*self.entries, None, Some(*self.ignores)) + all_assets_from_entries_filtered(self.entries(), None, Some(self.ignores())) .await? .iter() .map(async |m| { base_dir .get_relative_path_to(&*m.path().await?) - .context("failed to compute relative path for server nft.json") + .context("failed to compute relative path for server NFT JSON") }) .try_join() .await?; @@ -289,14 +106,14 @@ impl Asset for ServerNftJsonAsset { // A few hardcoded files (not recursive) server_output_assets.push("./package.json".into()); - let next_dir = get_next_package(self.project.project_path().owned().await?).await?; + let next_dir = get_next_package(this.project.project_path().owned().await?).await?; for ty in ["app-page", "pages"] { let dir = next_dir.join(&format!("dist/server/route-modules/{ty}"))?; let module_path = dir.join("module.compiled.js")?; server_output_assets.push( base_dir .get_relative_path_to(&module_path) - .context("failed to compute relative path for server nft.json")?, + .context("failed to compute relative path for server NFT JSON")?, ); let contexts_dir = dir.join("vendored/contexts")?; @@ -314,7 +131,7 @@ impl Asset for ServerNftJsonAsset { server_output_assets.push( base_dir .get_relative_path_to(file) - .context("failed to compute relative path for server nft.json")?, + .context("failed to compute relative path for server NFT JSON")?, ) } } @@ -334,3 +151,204 @@ impl Asset for ServerNftJsonAsset { Ok(AssetContent::file(File::from(json.to_string()).into())) } } + +#[turbo_tasks::value_impl] +impl ServerNftJsonAsset { + #[turbo_tasks::function] + async fn entries(&self) -> Result> { + let is_standalone = *self.project.next_config().is_standalone().await?; + + let asset_context = Vc::upcast(externals_tracing_module_context( + ExternalType::CommonJs, + get_tracing_compile_time_info(), + )); + + let project_path = self.project.project_path().owned().await?; + + let next_resolve_origin = Vc::upcast(PlainResolveOrigin::new( + asset_context, + get_next_package(project_path.clone()).await?.join("_")?, + )); + + let cache_handler = self + .project + .next_config() + .cache_handler(project_path.clone()) + .await?; + let cache_handlers = self + .project + .next_config() + .experimental_cache_handlers(project_path.clone()) + .await?; + + // These are used by packages/next/src/server/require-hook.ts + let shared_entries = ["styled-jsx", "styled-jsx/style", "styled-jsx/style.js"]; + + let cache_handler_entries = cache_handler + .into_iter() + .chain(cache_handlers.into_iter()) + .map(|f| { + asset_context + .process( + Vc::upcast(FileSource::new(f.clone())), + ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined), + ) + .module() + }); + + let entries = match self.ty { + ServerNftType::Full => Either::Left( + if is_standalone { + Either::Left( + [ + "next/dist/server/lib/start-server", + "next/dist/server/next", + "next/dist/server/require-hook", + ] + .into_iter(), + ) + } else { + Either::Right(std::iter::empty()) + } + .chain(std::iter::once("next/dist/server/next-server")), + ), + ServerNftType::Minimal => Either::Right(std::iter::once( + "next/dist/compiled/next-server/server.runtime.prod", + )), + }; + + Ok(Vc::cell( + cache_handler_entries + .chain( + shared_entries + .into_iter() + .chain(entries) + .map(async |path| { + Ok(cjs_resolve( + next_resolve_origin, + Request::parse_string(path.into()), + CommonJsReferenceSubType::Undefined, + None, + false, + ) + .primary_modules() + .await? + .into_iter() + .map(|m| **m)) + }) + .try_flat_join() + .await?, + ) + .map(|m| Vc::upcast::>(TracedAsset::new(m)).to_resolved()) + .try_join() + .await?, + )) + } + + #[turbo_tasks::function] + async fn ignores(&self) -> Result> { + let is_standalone = *self.project.next_config().is_standalone().await?; + let has_next_support = *self.project.next_config().ci_has_next_support().await?; + let project_path = self.project.project_path().owned().await?; + + let output_file_tracing_excludes = self + .project + .next_config() + .output_file_tracing_excludes() + .await?; + let mut additional_ignores = BTreeSet::new(); + if let Some(output_file_tracing_excludes) = output_file_tracing_excludes + .as_ref() + .and_then(Value::as_object) + { + for (glob_pattern, exclude_patterns) in output_file_tracing_excludes { + // Check if the route matches the glob pattern + let glob = Glob::new(RcStr::from(glob_pattern.clone()), Default::default()).await?; + if glob.matches("next-server") + && let Some(patterns) = exclude_patterns.as_array() + { + for pattern in patterns { + if let Some(pattern_str) = pattern.as_str() { + let (glob, root) = relativize_glob(pattern_str, project_path.clone())?; + let glob = if root.path.is_empty() { + glob.to_string() + } else { + format!("{root}/{glob}") + }; + additional_ignores.insert(glob); + } + } + } + } + } + + let server_ignores_glob = [ + "**/node_modules/react{,-dom,-server-dom-turbopack}/**/*.development.js", + "**/*.d.ts", + "**/*.map", + "**/next/dist/pages/**/*", + "**/next/dist/compiled/next-server/**/*.dev.js", + "**/next/dist/compiled/webpack/*", + "**/node_modules/webpack5/**/*", + "**/next/dist/server/lib/route-resolver*", + "**/next/dist/compiled/semver/semver/**/*.js", + "**/next/dist/compiled/jest-worker/**/*", + // Turbopack doesn't support AMP + "**/next/dist/compiled/@ampproject/toolbox-optimizer/**/*", + // -- The following were added for Turbopack specifically -- + // client/components/use-action-queue.ts has a process.env.NODE_ENV guard, but we can't set that due to React: https://github.com/vercel/next.js/pull/75254 + "**/next/dist/next-devtools/userspace/use-app-dev-rendering-indicator.js", + // client/components/app-router.js has a process.env.NODE_ENV guard, but we + // can't set that. + "**/next/dist/client/dev/hot-reloader/app/hot-reloader-app.js", + // server/lib/router-server.js doesn't guard this require: + "**/next/dist/server/lib/router-utils/setup-dev-bundler.js", + // server/next.js doesn't guard this require + "**/next/dist/server/dev/next-dev-server.js", + // next/dist/compiled/babel* pulls in this, but we never actually transpile at + // deploy-time + "**/next/dist/compiled/browserslist/**", + ] + .into_iter() + .chain(additional_ignores.iter().map(|s| s.as_str())) + // only ignore image-optimizer code when + // this is being handled outside of next-server + .chain(if has_next_support { + Either::Left( + [ + "**/node_modules/sharp/**/*", + "**/@img/sharp-libvips*/**/*", + "**/next/dist/server/image-optimizer.js", + ] + .into_iter(), + ) + } else { + Either::Right(std::iter::empty()) + }) + .chain(if is_standalone { + Either::Left(std::iter::empty()) + } else { + Either::Right(["**/*/next/dist/server/next.js", "**/*/next/dist/bin/next"].into_iter()) + }) + .map(|g| Glob::new(g.into(), Default::default())) + .collect::>(); + + Ok(match self.ty { + ServerNftType::Full => Glob::alternatives(server_ignores_glob), + ServerNftType::Minimal => Glob::alternatives( + server_ignores_glob + .into_iter() + .chain( + [ + "**/next/dist/compiled/edge-runtime/**/*", + "**/next/dist/server/web/sandbox/**/*", + "**/next/dist/server/post-process.js", + ] + .into_iter() + .map(|g| Glob::new(g.into(), Default::default())), + ) + .collect(), + ), + }) + } +} diff --git a/crates/next-api/src/nft_json.rs b/crates/next-api/src/nft_json.rs index 9160e079b8704a..a25cfa5b97b706 100644 --- a/crates/next-api/src/nft_json.rs +++ b/crates/next-api/src/nft_json.rs @@ -350,7 +350,10 @@ impl Asset for NftJsonAsset { /// traversal doesn't need to consider them and can just traverse 'down' the tree. /// The main alternative is to merge glob evaluation with directory traversal which is what the npm /// `glob` package does, but this would be a substantial rewrite.` -fn relativize_glob(glob: &str, relative_to: FileSystemPath) -> Result<(&str, FileSystemPath)> { +pub(crate) fn relativize_glob( + glob: &str, + relative_to: FileSystemPath, +) -> Result<(&str, FileSystemPath)> { let mut relative_to = relative_to; let mut processed_glob = glob; loop { From 600e10c7289205608bb34a6a03901114519c0e5a Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 29 Aug 2025 16:39:51 +0200 Subject: [PATCH 10/10] Smaller snapshot --- .../next-server-nft/next-server-nft.test.ts | 440 ++---------------- 1 file changed, 26 insertions(+), 414 deletions(-) diff --git a/test/production/next-server-nft/next-server-nft.test.ts b/test/production/next-server-nft/next-server-nft.test.ts index cef37121417fdb..08818c87826217 100644 --- a/test/production/next-server-nft/next-server-nft.test.ts +++ b/test/production/next-server-nft/next-server-nft.test.ts @@ -71,7 +71,29 @@ import fs from 'fs' it('should not trace too many files in next-server.js.nft.json', async () => { let trace = await readNormalizedNFT('.next/next-server.js.nft.json') - expect(trace).toMatchInlineSnapshot(` + + // Group the entries together so that the snapshot doesn't change too often. + // This trace contains quite a lot of files that aren't actually needed. But there isn't much + // that Turbopack itself can do about that. + + let traceGrouped = [ + ...new Set( + trace.map((file: string) => { + if (file.startsWith('/node_modules/next/dist/client/')) { + return '/node_modules/next/dist/client/*' + } + if (file.startsWith('/node_modules/next/dist/server/')) { + return '/node_modules/next/dist/server/*' + } + if (file.startsWith('/node_modules/next/dist/shared/')) { + return '/node_modules/next/dist/shared/*' + } + return file + }) + ), + ] + + expect(traceGrouped).toMatchInlineSnapshot(` [ "/node_modules/@next/env/dist/index.js", "/node_modules/@swc/helpers/cjs/_class_private_field_loose_base.cjs", @@ -93,93 +115,7 @@ import fs from 'fs' "/node_modules/next/dist/build/segment-config/app/app-segment-config.js", "/node_modules/next/dist/build/segment-config/app/app-segments.js", "/node_modules/next/dist/build/static-paths/utils.js", - "/node_modules/next/dist/client/add-base-path.js", - "/node_modules/next/dist/client/app-build-id.js", - "/node_modules/next/dist/client/app-call-server.js", - "/node_modules/next/dist/client/app-find-source-map-url.js", - "/node_modules/next/dist/client/assign-location.js", - "/node_modules/next/dist/client/components/app-router-announcer.js", - "/node_modules/next/dist/client/components/app-router-headers.js", - "/node_modules/next/dist/client/components/app-router-instance.js", - "/node_modules/next/dist/client/components/app-router.js", - "/node_modules/next/dist/client/components/builtin/default.js", - "/node_modules/next/dist/client/components/builtin/global-error.js", - "/node_modules/next/dist/client/components/dev-root-http-access-fallback-boundary.js", - "/node_modules/next/dist/client/components/error-boundary.js", - "/node_modules/next/dist/client/components/errors/graceful-degrade-boundary.js", - "/node_modules/next/dist/client/components/errors/root-error-boundary.js", - "/node_modules/next/dist/client/components/forbidden.js", - "/node_modules/next/dist/client/components/handle-isr-error.js", - "/node_modules/next/dist/client/components/hooks-server-context.js", - "/node_modules/next/dist/client/components/http-access-fallback/error-boundary.js", - "/node_modules/next/dist/client/components/http-access-fallback/http-access-fallback.js", - "/node_modules/next/dist/client/components/is-next-router-error.js", - "/node_modules/next/dist/client/components/links.js", - "/node_modules/next/dist/client/components/match-segments.js", - "/node_modules/next/dist/client/components/nav-failure-handler.js", - "/node_modules/next/dist/client/components/navigation-untracked.js", - "/node_modules/next/dist/client/components/navigation.js", - "/node_modules/next/dist/client/components/navigation.react-server.js", - "/node_modules/next/dist/client/components/not-found.js", - "/node_modules/next/dist/client/components/promise-queue.js", - "/node_modules/next/dist/client/components/redirect-boundary.js", - "/node_modules/next/dist/client/components/redirect-error.js", - "/node_modules/next/dist/client/components/redirect-status-code.js", - "/node_modules/next/dist/client/components/redirect.js", - "/node_modules/next/dist/client/components/router-reducer/aliased-prefetch-navigations.js", - "/node_modules/next/dist/client/components/router-reducer/apply-flight-data.js", - "/node_modules/next/dist/client/components/router-reducer/apply-router-state-patch-to-tree.js", - "/node_modules/next/dist/client/components/router-reducer/clear-cache-node-data-for-segment-path.js", - "/node_modules/next/dist/client/components/router-reducer/compute-changed-path.js", - "/node_modules/next/dist/client/components/router-reducer/create-href-from-url.js", - "/node_modules/next/dist/client/components/router-reducer/create-initial-router-state.js", - "/node_modules/next/dist/client/components/router-reducer/create-router-cache-key.js", - "/node_modules/next/dist/client/components/router-reducer/fetch-server-response.js", - "/node_modules/next/dist/client/components/router-reducer/fill-cache-with-new-subtree-data.js", - "/node_modules/next/dist/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.js", - "/node_modules/next/dist/client/components/router-reducer/handle-mutable.js", - "/node_modules/next/dist/client/components/router-reducer/handle-segment-mismatch.js", - "/node_modules/next/dist/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.js", - "/node_modules/next/dist/client/components/router-reducer/invalidate-cache-by-router-state.js", - "/node_modules/next/dist/client/components/router-reducer/is-navigating-to-new-root-layout.js", - "/node_modules/next/dist/client/components/router-reducer/ppr-navigations.js", - "/node_modules/next/dist/client/components/router-reducer/prefetch-cache-utils.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/find-head-in-cache.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/get-segment-value.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/has-interception-route-in-current-tree.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/hmr-refresh-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/navigate-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/prefetch-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/refresh-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/restore-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/server-action-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/reducers/server-patch-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/refetch-inactive-parallel-segments.js", - "/node_modules/next/dist/client/components/router-reducer/router-reducer-types.js", - "/node_modules/next/dist/client/components/router-reducer/router-reducer.js", - "/node_modules/next/dist/client/components/router-reducer/set-cache-busting-search-param.js", - "/node_modules/next/dist/client/components/router-reducer/should-hard-navigate.js", - "/node_modules/next/dist/client/components/segment-cache-impl/cache-key.js", - "/node_modules/next/dist/client/components/segment-cache-impl/cache.js", - "/node_modules/next/dist/client/components/segment-cache-impl/lru.js", - "/node_modules/next/dist/client/components/segment-cache-impl/navigation.js", - "/node_modules/next/dist/client/components/segment-cache-impl/prefetch.js", - "/node_modules/next/dist/client/components/segment-cache-impl/scheduler.js", - "/node_modules/next/dist/client/components/segment-cache-impl/tuple-map.js", - "/node_modules/next/dist/client/components/segment-cache.js", - "/node_modules/next/dist/client/components/static-generation-bailout.js", - "/node_modules/next/dist/client/components/unauthorized.js", - "/node_modules/next/dist/client/components/unrecognized-action-error.js", - "/node_modules/next/dist/client/components/unresolved-thenable.js", - "/node_modules/next/dist/client/components/unstable-rethrow.browser.js", - "/node_modules/next/dist/client/components/unstable-rethrow.js", - "/node_modules/next/dist/client/components/unstable-rethrow.server.js", - "/node_modules/next/dist/client/components/use-action-queue.js", - "/node_modules/next/dist/client/flight-data-helpers.js", - "/node_modules/next/dist/client/has-base-path.js", - "/node_modules/next/dist/client/normalize-trailing-slash.js", - "/node_modules/next/dist/client/remove-base-path.js", - "/node_modules/next/dist/client/route-params.js", + "/node_modules/next/dist/client/*", "/node_modules/next/dist/compiled/@edge-runtime/cookies/index.js", "/node_modules/next/dist/compiled/@hapi/accept/index.js", "/node_modules/next/dist/compiled/@mswjs/interceptors/ClientRequest/index.js", @@ -264,332 +200,8 @@ import fs from 'fs' "/node_modules/next/dist/lib/url.js", "/node_modules/next/dist/lib/wait.js", "/node_modules/next/dist/next-devtools/server/shared.js", - "/node_modules/next/dist/server/ReactDOMServerPages.js", - "/node_modules/next/dist/server/after/after-context.js", - "/node_modules/next/dist/server/after/awaiter.js", - "/node_modules/next/dist/server/after/builtin-request-context.js", - "/node_modules/next/dist/server/api-utils/get-cookie-parser.js", - "/node_modules/next/dist/server/api-utils/index.js", - "/node_modules/next/dist/server/api-utils/node/try-get-preview-data.js", - "/node_modules/next/dist/server/app-render/action-async-storage-instance.js", - "/node_modules/next/dist/server/app-render/action-async-storage.external.js", - "/node_modules/next/dist/server/app-render/action-handler.js", - "/node_modules/next/dist/server/app-render/action-utils.js", - "/node_modules/next/dist/server/app-render/after-task-async-storage-instance.js", - "/node_modules/next/dist/server/app-render/after-task-async-storage.external.js", - "/node_modules/next/dist/server/app-render/app-render-prerender-utils.js", - "/node_modules/next/dist/server/app-render/app-render-render-utils.js", - "/node_modules/next/dist/server/app-render/app-render.js", - "/node_modules/next/dist/server/app-render/async-local-storage.js", - "/node_modules/next/dist/server/app-render/cache-signal.js", - "/node_modules/next/dist/server/app-render/create-component-styles-and-scripts.js", - "/node_modules/next/dist/server/app-render/create-component-tree.js", - "/node_modules/next/dist/server/app-render/create-error-handler.js", - "/node_modules/next/dist/server/app-render/create-flight-router-state-from-loader-tree.js", - "/node_modules/next/dist/server/app-render/csrf-protection.js", - "/node_modules/next/dist/server/app-render/dynamic-rendering.js", - "/node_modules/next/dist/server/app-render/encryption-utils.js", - "/node_modules/next/dist/server/app-render/flight-render-result.js", - "/node_modules/next/dist/server/app-render/get-asset-query-string.js", - "/node_modules/next/dist/server/app-render/get-css-inlined-link-tags.js", - "/node_modules/next/dist/server/app-render/get-layer-assets.js", - "/node_modules/next/dist/server/app-render/get-preloadable-fonts.js", - "/node_modules/next/dist/server/app-render/get-script-nonce-from-header.js", - "/node_modules/next/dist/server/app-render/get-segment-param.js", - "/node_modules/next/dist/server/app-render/get-short-dynamic-param-type.js", - "/node_modules/next/dist/server/app-render/has-loading-component-in-tree.js", - "/node_modules/next/dist/server/app-render/interop-default.js", - "/node_modules/next/dist/server/app-render/make-get-server-inserted-html.js", - "/node_modules/next/dist/server/app-render/metadata-insertion/create-server-inserted-metadata.js", - "/node_modules/next/dist/server/app-render/module-loading/track-module-loading.external.js", - "/node_modules/next/dist/server/app-render/module-loading/track-module-loading.instance.js", - "/node_modules/next/dist/server/app-render/parse-and-validate-flight-router-state.js", - "/node_modules/next/dist/server/app-render/parse-loader-tree.js", - "/node_modules/next/dist/server/app-render/postponed-state.js", - "/node_modules/next/dist/server/app-render/prospective-render-utils.js", - "/node_modules/next/dist/server/app-render/react-large-shell-error.js", - "/node_modules/next/dist/server/app-render/react-server.node.js", - "/node_modules/next/dist/server/app-render/render-css-resource.js", - "/node_modules/next/dist/server/app-render/required-scripts.js", - "/node_modules/next/dist/server/app-render/segment-explorer-path.js", - "/node_modules/next/dist/server/app-render/server-inserted-html.js", - "/node_modules/next/dist/server/app-render/strip-flight-headers.js", - "/node_modules/next/dist/server/app-render/types.js", - "/node_modules/next/dist/server/app-render/use-flight-response.js", - "/node_modules/next/dist/server/app-render/walk-tree-with-flight-router-state.js", - "/node_modules/next/dist/server/app-render/work-async-storage-instance.js", - "/node_modules/next/dist/server/app-render/work-async-storage.external.js", - "/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.js", - "/node_modules/next/dist/server/app-render/work-unit-async-storage.external.js", - "/node_modules/next/dist/server/async-storage/draft-mode-provider.js", - "/node_modules/next/dist/server/async-storage/request-store.js", - "/node_modules/next/dist/server/async-storage/work-store.js", - "/node_modules/next/dist/server/base-http/helpers.js", - "/node_modules/next/dist/server/base-http/index.js", - "/node_modules/next/dist/server/base-http/node.js", - "/node_modules/next/dist/server/base-server.js", - "/node_modules/next/dist/server/body-streams.js", - "/node_modules/next/dist/server/client-component-renderer-logger.js", - "/node_modules/next/dist/server/crypto-utils.js", - "/node_modules/next/dist/server/dev/node-stack-frames.js", - "/node_modules/next/dist/server/dynamic-rendering-utils.js", - "/node_modules/next/dist/server/htmlescape.js", - "/node_modules/next/dist/server/image-optimizer.js", - "/node_modules/next/dist/server/instrumentation/utils.js", - "/node_modules/next/dist/server/internal-utils.js", - "/node_modules/next/dist/server/lib/app-dir-module.js", - "/node_modules/next/dist/server/lib/async-callback-set.js", - "/node_modules/next/dist/server/lib/cache-control.js", - "/node_modules/next/dist/server/lib/cache-handlers/default.external.js", - "/node_modules/next/dist/server/lib/clone-response.js", - "/node_modules/next/dist/server/lib/decode-query-path-parameter.js", - "/node_modules/next/dist/server/lib/dedupe-fetch.js", - "/node_modules/next/dist/server/lib/etag.js", - "/node_modules/next/dist/server/lib/experimental/ppr.js", - "/node_modules/next/dist/server/lib/fix-mojibake.js", - "/node_modules/next/dist/server/lib/format-hostname.js", - "/node_modules/next/dist/server/lib/i18n-provider.js", - "/node_modules/next/dist/server/lib/implicit-tags.js", - "/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js", - "/node_modules/next/dist/server/lib/incremental-cache/index.js", - "/node_modules/next/dist/server/lib/incremental-cache/memory-cache.external.js", - "/node_modules/next/dist/server/lib/incremental-cache/shared-cache-controls.external.js", - "/node_modules/next/dist/server/lib/incremental-cache/tags-manifest.external.js", - "/node_modules/next/dist/server/lib/is-ipv6.js", - "/node_modules/next/dist/server/lib/lazy-result.js", - "/node_modules/next/dist/server/lib/lru-cache.js", - "/node_modules/next/dist/server/lib/match-next-data-pathname.js", - "/node_modules/next/dist/server/lib/mock-request.js", - "/node_modules/next/dist/server/lib/module-loader/node-module-loader.js", - "/node_modules/next/dist/server/lib/node-fs-methods.js", - "/node_modules/next/dist/server/lib/parse-stack.js", - "/node_modules/next/dist/server/lib/patch-fetch.js", - "/node_modules/next/dist/server/lib/patch-set-header.js", - "/node_modules/next/dist/server/lib/router-utils/decode-path-params.js", - "/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js", - "/node_modules/next/dist/server/lib/router-utils/instrumentation-node-extensions.js", - "/node_modules/next/dist/server/lib/router-utils/is-postpone.js", - "/node_modules/next/dist/server/lib/router-utils/router-server-context.js", - "/node_modules/next/dist/server/lib/server-action-request-meta.js", - "/node_modules/next/dist/server/lib/server-ipc/utils.js", - "/node_modules/next/dist/server/lib/source-maps.js", - "/node_modules/next/dist/server/lib/streaming-metadata.js", - "/node_modules/next/dist/server/lib/to-route.js", - "/node_modules/next/dist/server/lib/trace/constants.js", - "/node_modules/next/dist/server/lib/trace/tracer.js", - "/node_modules/next/dist/server/lib/trace/utils.js", - "/node_modules/next/dist/server/load-components.js", - "/node_modules/next/dist/server/load-manifest.external.js", - "/node_modules/next/dist/server/next-server.js", - "/node_modules/next/dist/server/node-environment-baseline.js", - "/node_modules/next/dist/server/node-environment-extensions/console-dev.js", - "/node_modules/next/dist/server/node-environment-extensions/date.js", - "/node_modules/next/dist/server/node-environment-extensions/error-inspect.js", - "/node_modules/next/dist/server/node-environment-extensions/node-crypto.js", - "/node_modules/next/dist/server/node-environment-extensions/random.js", - "/node_modules/next/dist/server/node-environment-extensions/utils.js", - "/node_modules/next/dist/server/node-environment-extensions/web-crypto.js", - "/node_modules/next/dist/server/node-environment.js", - "/node_modules/next/dist/server/node-polyfill-crypto.js", - "/node_modules/next/dist/server/normalizers/absolute-filename-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/app/app-bundle-path-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/app/app-filename-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/app/app-page-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/app/app-pathname-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/app/index.js", - "/node_modules/next/dist/server/normalizers/built/pages/index.js", - "/node_modules/next/dist/server/normalizers/built/pages/pages-bundle-path-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/pages/pages-filename-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/pages/pages-page-normalizer.js", - "/node_modules/next/dist/server/normalizers/built/pages/pages-pathname-normalizer.js", - "/node_modules/next/dist/server/normalizers/locale-route-normalizer.js", - "/node_modules/next/dist/server/normalizers/normalizers.js", - "/node_modules/next/dist/server/normalizers/prefixing-normalizer.js", - "/node_modules/next/dist/server/normalizers/request/next-data.js", - "/node_modules/next/dist/server/normalizers/request/prefetch-rsc.js", - "/node_modules/next/dist/server/normalizers/request/prefix.js", - "/node_modules/next/dist/server/normalizers/request/rsc.js", - "/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.js", - "/node_modules/next/dist/server/normalizers/request/suffix.js", - "/node_modules/next/dist/server/normalizers/underscore-normalizer.js", - "/node_modules/next/dist/server/normalizers/wrap-normalizer-fn.js", - "/node_modules/next/dist/server/patch-error-inspect.js", - "/node_modules/next/dist/server/pipe-readable.js", - "/node_modules/next/dist/server/post-process.js", - "/node_modules/next/dist/server/render-result.js", - "/node_modules/next/dist/server/render.js", - "/node_modules/next/dist/server/request-meta.js", - "/node_modules/next/dist/server/request/fallback-params.js", - "/node_modules/next/dist/server/require-hook.js", - "/node_modules/next/dist/server/require.js", - "/node_modules/next/dist/server/response-cache/index.js", - "/node_modules/next/dist/server/response-cache/types.js", - "/node_modules/next/dist/server/response-cache/utils.js", - "/node_modules/next/dist/server/resume-data-cache/cache-store.js", - "/node_modules/next/dist/server/resume-data-cache/resume-data-cache.js", - "/node_modules/next/dist/server/revalidation-utils.js", - "/node_modules/next/dist/server/route-kind.js", - "/node_modules/next/dist/server/route-matcher-managers/default-route-matcher-manager.js", - "/node_modules/next/dist/server/route-matcher-providers/app-page-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matcher-providers/app-route-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matcher-providers/helpers/cached-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matcher-providers/helpers/manifest-loaders/server-manifest-loader.js", - "/node_modules/next/dist/server/route-matcher-providers/manifest-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matcher-providers/pages-api-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matcher-providers/pages-route-matcher-provider.js", - "/node_modules/next/dist/server/route-matchers/app-page-route-matcher.js", - "/node_modules/next/dist/server/route-matchers/app-route-route-matcher.js", - "/node_modules/next/dist/server/route-matchers/locale-route-matcher.js", - "/node_modules/next/dist/server/route-matchers/pages-api-route-matcher.js", - "/node_modules/next/dist/server/route-matchers/pages-route-matcher.js", - "/node_modules/next/dist/server/route-matchers/route-matcher.js", - "/node_modules/next/dist/server/route-matches/pages-api-route-match.js", - "/node_modules/next/dist/server/route-modules/app-page/helpers/prerender-manifest-matcher.js", - "/node_modules/next/dist/server/route-modules/app-page/module.compiled.js", - "/node_modules/next/dist/server/route-modules/app-page/module.js", - "/node_modules/next/dist/server/route-modules/app-page/module.render.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/amp-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/app-router-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/head-manager-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/hooks-client-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/image-config-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/router-context.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/server-inserted-html.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.js", - "/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.js", - "/node_modules/next/dist/server/route-modules/checks.js", - "/node_modules/next/dist/server/route-modules/pages/module.compiled.js", - "/node_modules/next/dist/server/route-modules/pages/module.js", - "/node_modules/next/dist/server/route-modules/pages/module.render.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/amp-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/app-router-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/head-manager-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/hooks-client-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/html-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/image-config-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/loadable.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/router-context.js", - "/node_modules/next/dist/server/route-modules/pages/vendored/contexts/server-inserted-html.js", - "/node_modules/next/dist/server/route-modules/route-module.js", - "/node_modules/next/dist/server/send-payload.js", - "/node_modules/next/dist/server/send-response.js", - "/node_modules/next/dist/server/serve-static.js", - "/node_modules/next/dist/server/server-utils.js", - "/node_modules/next/dist/server/setup-http-agent-env.js", - "/node_modules/next/dist/server/stream-utils/encoded-tags.js", - "/node_modules/next/dist/server/stream-utils/node-web-streams-helper.js", - "/node_modules/next/dist/server/stream-utils/uint8array-helpers.js", - "/node_modules/next/dist/server/use-cache/handlers.js", - "/node_modules/next/dist/server/utils.js", - "/node_modules/next/dist/server/web/adapter.js", - "/node_modules/next/dist/server/web/error.js", - "/node_modules/next/dist/server/web/get-edge-preview-props.js", - "/node_modules/next/dist/server/web/globals.js", - "/node_modules/next/dist/server/web/next-url.js", - "/node_modules/next/dist/server/web/sandbox/context.js", - "/node_modules/next/dist/server/web/sandbox/fetch-inline-assets.js", - "/node_modules/next/dist/server/web/sandbox/index.js", - "/node_modules/next/dist/server/web/sandbox/resource-managers.js", - "/node_modules/next/dist/server/web/sandbox/sandbox.js", - "/node_modules/next/dist/server/web/spec-extension/adapters/headers.js", - "/node_modules/next/dist/server/web/spec-extension/adapters/next-request.js", - "/node_modules/next/dist/server/web/spec-extension/adapters/reflect.js", - "/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.js", - "/node_modules/next/dist/server/web/spec-extension/cookies.js", - "/node_modules/next/dist/server/web/spec-extension/fetch-event.js", - "/node_modules/next/dist/server/web/spec-extension/request.js", - "/node_modules/next/dist/server/web/spec-extension/response.js", - "/node_modules/next/dist/server/web/utils.js", - "/node_modules/next/dist/server/web/web-on-close.js", - "/node_modules/next/dist/shared/lib/amp-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/amp-mode.js", - "/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/app-router-types.js", - "/node_modules/next/dist/shared/lib/constants.js", - "/node_modules/next/dist/shared/lib/deep-freeze.js", - "/node_modules/next/dist/shared/lib/encode-uri-path.js", - "/node_modules/next/dist/shared/lib/entry-constants.js", - "/node_modules/next/dist/shared/lib/error-source.js", - "/node_modules/next/dist/shared/lib/errors/constants.js", - "/node_modules/next/dist/shared/lib/escape-regexp.js", - "/node_modules/next/dist/shared/lib/get-hostname.js", - "/node_modules/next/dist/shared/lib/hash.js", - "/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/head.js", - "/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/html-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/i18n/detect-domain-locale.js", - "/node_modules/next/dist/shared/lib/i18n/normalize-locale-path.js", - "/node_modules/next/dist/shared/lib/image-blur-svg.js", - "/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/image-config.js", - "/node_modules/next/dist/shared/lib/invariant-error.js", - "/node_modules/next/dist/shared/lib/is-internal.js", - "/node_modules/next/dist/shared/lib/is-plain-object.js", - "/node_modules/next/dist/shared/lib/is-thenable.js", - "/node_modules/next/dist/shared/lib/isomorphic/path.js", - "/node_modules/next/dist/shared/lib/lazy-dynamic/bailout-to-csr.js", - "/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/loadable.shared-runtime.js", - "/node_modules/next/dist/shared/lib/match-local-pattern.js", - "/node_modules/next/dist/shared/lib/match-remote-pattern.js", - "/node_modules/next/dist/shared/lib/modern-browserslist-target.js", - "/node_modules/next/dist/shared/lib/no-fallback-error.external.js", - "/node_modules/next/dist/shared/lib/page-path/absolute-path-to-page.js", - "/node_modules/next/dist/shared/lib/page-path/denormalize-page-path.js", - "/node_modules/next/dist/shared/lib/page-path/ensure-leading-slash.js", - "/node_modules/next/dist/shared/lib/page-path/normalize-data-path.js", - "/node_modules/next/dist/shared/lib/page-path/normalize-page-path.js", - "/node_modules/next/dist/shared/lib/page-path/normalize-path-sep.js", - "/node_modules/next/dist/shared/lib/page-path/remove-page-path-tail.js", - "/node_modules/next/dist/shared/lib/promise-with-resolvers.js", - "/node_modules/next/dist/shared/lib/router-context.shared-runtime.js", - "/node_modules/next/dist/shared/lib/router/adapters.js", - "/node_modules/next/dist/shared/lib/router/utils/add-locale.js", - "/node_modules/next/dist/shared/lib/router/utils/add-path-prefix.js", - "/node_modules/next/dist/shared/lib/router/utils/add-path-suffix.js", - "/node_modules/next/dist/shared/lib/router/utils/app-paths.js", - "/node_modules/next/dist/shared/lib/router/utils/as-path-to-search-params.js", - "/node_modules/next/dist/shared/lib/router/utils/cache-busting-search-param.js", - "/node_modules/next/dist/shared/lib/router/utils/escape-path-delimiters.js", - "/node_modules/next/dist/shared/lib/router/utils/format-next-pathname-info.js", - "/node_modules/next/dist/shared/lib/router/utils/format-url.js", - "/node_modules/next/dist/shared/lib/router/utils/get-dynamic-param.js", - "/node_modules/next/dist/shared/lib/router/utils/get-next-pathname-info.js", - "/node_modules/next/dist/shared/lib/router/utils/get-route-from-asset-path.js", - "/node_modules/next/dist/shared/lib/router/utils/html-bots.js", - "/node_modules/next/dist/shared/lib/router/utils/index.js", - "/node_modules/next/dist/shared/lib/router/utils/interception-routes.js", - "/node_modules/next/dist/shared/lib/router/utils/is-bot.js", - "/node_modules/next/dist/shared/lib/router/utils/is-dynamic.js", - "/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.js", - "/node_modules/next/dist/shared/lib/router/utils/parse-path.js", - "/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.js", - "/node_modules/next/dist/shared/lib/router/utils/parse-url.js", - "/node_modules/next/dist/shared/lib/router/utils/path-has-prefix.js", - "/node_modules/next/dist/shared/lib/router/utils/path-match.js", - "/node_modules/next/dist/shared/lib/router/utils/prepare-destination.js", - "/node_modules/next/dist/shared/lib/router/utils/querystring.js", - "/node_modules/next/dist/shared/lib/router/utils/relativize-url.js", - "/node_modules/next/dist/shared/lib/router/utils/remove-path-prefix.js", - "/node_modules/next/dist/shared/lib/router/utils/remove-trailing-slash.js", - "/node_modules/next/dist/shared/lib/router/utils/route-match-utils.js", - "/node_modules/next/dist/shared/lib/router/utils/route-matcher.js", - "/node_modules/next/dist/shared/lib/router/utils/route-regex.js", - "/node_modules/next/dist/shared/lib/router/utils/sorted-routes.js", - "/node_modules/next/dist/shared/lib/runtime-config.external.js", - "/node_modules/next/dist/shared/lib/segment-cache/output-export-prefetch-encoding.js", - "/node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.js", - "/node_modules/next/dist/shared/lib/segment.js", - "/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.js", - "/node_modules/next/dist/shared/lib/server-reference-info.js", - "/node_modules/next/dist/shared/lib/side-effect.js", - "/node_modules/next/dist/shared/lib/utils.js", - "/node_modules/next/dist/shared/lib/utils/warn-once.js", - "/node_modules/next/dist/shared/lib/zod.js", + "/node_modules/next/dist/server/*", + "/node_modules/next/dist/shared/*", "/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js", "/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js", "/node_modules/react-dom/cjs/react-dom-server.browser.production.js",