diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index f8fa52aebbdcf..92caa1d190df6 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -1119,6 +1119,9 @@ impl Project { source_maps: self.next_config().client_source_maps(self.next_mode()), no_mangling: self.no_mangling(), scope_hoisting: self.next_config().turbo_scope_hoisting(self.next_mode()), + nested_async_chunking: self + .next_config() + .turbo_nested_async_chunking(self.next_mode(), true), debug_ids: self.next_config().turbopack_debug_ids(), should_use_absolute_url_references: self.next_config().inline_css(), })) @@ -1141,6 +1144,9 @@ impl Project { turbo_source_maps: self.next_config().server_source_maps(), no_mangling: self.no_mangling(), scope_hoisting: self.next_config().turbo_scope_hoisting(self.next_mode()), + nested_async_chunking: self + .next_config() + .turbo_nested_async_chunking(self.next_mode(), false), debug_ids: self.next_config().turbopack_debug_ids(), client_root: self.client_relative_path().owned().await?, asset_prefix: self.next_config().computed_asset_prefix().owned().await?, @@ -1169,6 +1175,9 @@ impl Project { turbo_source_maps: self.next_config().server_source_maps(), no_mangling: self.no_mangling(), scope_hoisting: self.next_config().turbo_scope_hoisting(self.next_mode()), + nested_async_chunking: self + .next_config() + .turbo_nested_async_chunking(self.next_mode(), false), client_root: self.client_relative_path().owned().await?, asset_prefix: self.next_config().computed_asset_prefix().owned().await?, }; diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index 1e8f066230f54..39c5f8bc09c58 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -426,6 +426,7 @@ pub struct ClientChunkingContextOptions { pub source_maps: Vc, pub no_mangling: Vc, pub scope_hoisting: Vc, + pub nested_async_chunking: Vc, pub debug_ids: Vc, pub should_use_absolute_url_references: Vc, } @@ -448,6 +449,7 @@ pub async fn get_client_chunking_context( source_maps, no_mangling, scope_hoisting, + nested_async_chunking, debug_ids, should_use_absolute_url_references, } = options; @@ -484,7 +486,8 @@ pub async fn get_client_chunking_context( .export_usage(*export_usage.await?) .module_id_strategy(module_id_strategy.to_resolved().await?) .debug_ids(*debug_ids.await?) - .should_use_absolute_url_references(*should_use_absolute_url_references.await?); + .should_use_absolute_url_references(*should_use_absolute_url_references.await?) + .nested_async_availability(*nested_async_chunking.await?); if next_mode.is_development() { builder = builder @@ -510,7 +513,6 @@ pub async fn get_client_chunking_context( }, ) .use_content_hashing(ContentHashing::Direct { length: 16 }) - .nested_async_availability(true) .module_merging(*scope_hoisting.await?); } diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index ba44eb1cca54f..371bdc1ab2fae 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -886,6 +886,8 @@ pub struct ExperimentalConfig { turbopack_source_maps: Option, turbopack_tree_shaking: Option, turbopack_scope_hoisting: Option, + turbopack_client_side_nested_async_chunking: Option, + turbopack_server_side_nested_async_chunking: Option, turbopack_import_type_bytes: Option, turbopack_use_system_tls_certs: Option, /// Disable automatic configuration of the sass loader. @@ -1790,6 +1792,29 @@ impl NextConfig { })) } + #[turbo_tasks::function] + pub async fn turbo_nested_async_chunking( + &self, + mode: Vc, + client_side: bool, + ) -> Result> { + let option = if client_side { + self.experimental + .turbopack_client_side_nested_async_chunking + } else { + self.experimental + .turbopack_server_side_nested_async_chunking + }; + Ok(Vc::cell(if let Some(value) = option { + value + } else { + match *mode.await? { + NextMode::Development => false, + NextMode::Build => client_side, + } + })) + } + #[turbo_tasks::function] pub async fn turbopack_import_type_bytes(&self) -> Vc { Vc::cell( diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index 2b5c06ced3b0d..c3e956782c984 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -208,6 +208,7 @@ pub struct EdgeChunkingContextOptions { pub turbo_source_maps: Vc, pub no_mangling: Vc, pub scope_hoisting: Vc, + pub nested_async_chunking: Vc, pub client_root: FileSystemPath, pub asset_prefix: RcStr, } @@ -229,6 +230,7 @@ pub async fn get_edge_chunking_context_with_client_assets( turbo_source_maps, no_mangling, scope_hoisting, + nested_async_chunking, client_root, asset_prefix, } = options; @@ -259,7 +261,8 @@ pub async fn get_edge_chunking_context_with_client_assets( SourceMapsType::None }) .module_id_strategy(module_id_strategy.to_resolved().await?) - .export_usage(*export_usage.await?); + .export_usage(*export_usage.await?) + .nested_async_availability(*nested_async_chunking.await?); if !next_mode.is_development() { builder = builder @@ -300,6 +303,7 @@ pub async fn get_edge_chunking_context( turbo_source_maps, no_mangling, scope_hoisting, + nested_async_chunking, client_root, asset_prefix, } = options; @@ -336,7 +340,8 @@ pub async fn get_edge_chunking_context( SourceMapsType::None }) .module_id_strategy(module_id_strategy.to_resolved().await?) - .export_usage(*export_usage.await?); + .export_usage(*export_usage.await?) + .nested_async_availability(*nested_async_chunking.await?); if !next_mode.is_development() { builder = builder diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index 63a2fa9f23af0..734e5bfebdfcb 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -1000,6 +1000,7 @@ pub struct ServerChunkingContextOptions { pub turbo_source_maps: Vc, pub no_mangling: Vc, pub scope_hoisting: Vc, + pub nested_async_chunking: Vc, pub debug_ids: Vc, pub client_root: FileSystemPath, pub asset_prefix: RcStr, @@ -1022,6 +1023,7 @@ pub async fn get_server_chunking_context_with_client_assets( turbo_source_maps, no_mangling, scope_hoisting, + nested_async_chunking, debug_ids, client_root, asset_prefix, @@ -1058,7 +1060,8 @@ pub async fn get_server_chunking_context_with_client_assets( .module_id_strategy(module_id_strategy.to_resolved().await?) .export_usage(*export_usage.await?) .file_tracing(next_mode.is_production()) - .debug_ids(*debug_ids.await?); + .debug_ids(*debug_ids.await?) + .nested_async_availability(*nested_async_chunking.await?); builder = builder.source_map_source_type(if next_mode.is_development() { SourceMapSourceType::AbsoluteFileUri @@ -1106,6 +1109,7 @@ pub async fn get_server_chunking_context( turbo_source_maps, no_mangling, scope_hoisting, + nested_async_chunking, debug_ids, client_root, asset_prefix, @@ -1142,7 +1146,8 @@ pub async fn get_server_chunking_context( .module_id_strategy(module_id_strategy.to_resolved().await?) .export_usage(*export_usage.await?) .file_tracing(next_mode.is_production()) - .debug_ids(*debug_ids.await?); + .debug_ids(*debug_ids.await?) + .nested_async_availability(*nested_async_chunking.await?); if next_mode.is_development() { builder = builder.source_map_source_type(SourceMapSourceType::AbsoluteFileUri); diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 03bfa8b4c0d14..071d641ba3759 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -301,6 +301,8 @@ export const experimentalSchema = { turbopackTreeShaking: z.boolean().optional(), turbopackRemoveUnusedExports: z.boolean().optional(), turbopackScopeHoisting: z.boolean().optional(), + turbopackClientSideNestedAsyncChunking: z.boolean().optional(), + turbopackServerSideNestedAsyncChunking: z.boolean().optional(), turbopackImportTypeBytes: z.boolean().optional(), turbopackUseSystemTlsCerts: z.boolean().optional(), turbopackUseBuiltinBabel: z.boolean().optional(), diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index fa23ce95f6416..1c0787efc54b5 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -413,6 +413,18 @@ export interface ExperimentalConfig { */ turbopackScopeHoisting?: boolean + /** + * Enable nested async chunking for client side assets. Defaults to true in build mode and false in dev mode. + * This optimization computes all possible paths through dynamic imports in the applications to figure out the modules needed at dynamic imports for every path. + */ + turbopackClientSideNestedAsyncChunking?: boolean + + /** + * Enable nested async chunking for server side assets. Defaults to false in dev and build mode. + * This optimization computes all possible paths through dynamic imports in the applications to figure out the modules needed at dynamic imports for every path. + */ + turbopackServerSideNestedAsyncChunking?: boolean + /** * Enable filesystem cache for the turbopack dev server. */