Repository: vercel/next.js
Pull request: Turbopack: fix chunking context caching

### What?

Fixes caching by changing arguments from `Option<RcStr>` to `Vc<Option<RcStr>>`.

This changes the argument from passed by value to passed by reference. This makes a big differences regarding caching when the string value is changing.

`Option<RcStr>`: When the string changes a completely new task is created resulting in ChunkingContext being in a new cell, which ends up creating new tasks for all functions that receive the ChunkingContext. This results in a lot of new tasks that need to be computed and stored.

`Vc<Option<RcStr>>`: When the string changes the existing task is invalidated and recomputed. The result is still the same cell and no new tasks for functions that receive the ChunkingContext are created. Only tasks that use the string are invalidated and recomputed.

Closes PACK-4896

Changed files:
filename: crates/next-api/src/project.rs
patch: @@ -1010,8 +1010,8 @@ impl Project {
             self.project_root_path(),
             self.client_relative_path(),
             rcstr!("/ROOT"),
-            self.next_config().computed_asset_prefix().owned().await?,
-            self.next_config().chunk_suffix_path().owned().await?,
+            self.next_config().computed_asset_prefix(),
+            self.next_config().chunk_suffix_path(),
             self.client_compile_time_info().environment(),
             self.next_mode(),
             self.module_ids(),
@@ -1068,9 +1068,9 @@ impl Project {
                 self.next_mode(),
                 self.project_root_path(),
                 self.node_root(),
-                self.node_root_to_root_path().owned().await?,
+                self.node_root_to_root_path(),
                 self.client_relative_path(),
-                self.next_config().computed_asset_prefix().owned().await?,
+                self.next_config().computed_asset_prefix(),
                 self.edge_compile_time_info().environment(),
                 self.module_ids(),
                 self.next_config().turbo_minify(self.next_mode()),
@@ -1083,7 +1083,7 @@ impl Project {
                 self.next_mode(),
                 self.project_root_path(),
                 self.node_root(),
-                self.node_root_to_root_path().owned().await?,
+                self.node_root_to_root_path(),
                 self.edge_compile_time_info().environment(),
                 self.module_ids(),
                 self.next_config().turbo_minify(self.next_mode()),

filename: crates/next-core/src/next_client/context.rs
patch: @@ -427,8 +427,8 @@ pub async fn get_client_chunking_context(
     root_path: ResolvedVc<FileSystemPath>,
     client_root: ResolvedVc<FileSystemPath>,
     client_root_to_root_path: RcStr,
-    asset_prefix: Option<RcStr>,
-    chunk_suffix_path: Option<RcStr>,
+    asset_prefix: ResolvedVc<Option<RcStr>>,
+    chunk_suffix_path: ResolvedVc<Option<RcStr>>,
     environment: ResolvedVc<Environment>,
     mode: Vc<NextMode>,
     module_id_strategy: ResolvedVc<Box<dyn ModuleIdStrategy>>,
@@ -438,6 +438,8 @@ pub async fn get_client_chunking_context(
     scope_hoisting: Vc<bool>,
 ) -> Result<Vc<Box<dyn ChunkingContext>>> {
     let next_mode = mode.await?;
+    let asset_prefix = asset_prefix.owned().await?;
+    let chunk_suffix_path = chunk_suffix_path.owned().await?;
     let mut builder = BrowserChunkingContext::builder(
         root_path,
         client_root,

filename: crates/next-core/src/next_edge/context.rs
patch: @@ -223,9 +223,9 @@ pub async fn get_edge_chunking_context_with_client_assets(
     mode: Vc<NextMode>,
     root_path: ResolvedVc<FileSystemPath>,
     node_root: ResolvedVc<FileSystemPath>,
-    output_root_to_root_path: RcStr,
+    output_root_to_root_path: ResolvedVc<RcStr>,
     client_root: ResolvedVc<FileSystemPath>,
-    asset_prefix: Option<RcStr>,
+    asset_prefix: ResolvedVc<Option<RcStr>>,
     environment: ResolvedVc<Environment>,
     module_id_strategy: ResolvedVc<Box<dyn ModuleIdStrategy>>,
     turbo_minify: Vc<bool>,
@@ -238,7 +238,7 @@ pub async fn get_edge_chunking_context_with_client_assets(
     let mut builder = BrowserChunkingContext::builder(
         root_path,
         output_root,
-        output_root_to_root_path,
+        output_root_to_root_path.owned().await?,
         client_root,
         output_root.join(rcstr!("chunks/ssr")).to_resolved().await?,
         client_root
@@ -248,7 +248,7 @@ pub async fn get_edge_chunking_context_with_client_assets(
         environment,
         next_mode.runtime_type(),
     )
-    .asset_base_path(asset_prefix)
+    .asset_base_path(asset_prefix.owned().await?)
     .minify_type(if *turbo_minify.await? {
         MinifyType::Minify {
             // React needs deterministic function names to work correctly.
@@ -291,7 +291,7 @@ pub async fn get_edge_chunking_context(
     mode: Vc<NextMode>,
     root_path: ResolvedVc<FileSystemPath>,
     node_root: ResolvedVc<FileSystemPath>,
-    node_root_to_root_path: RcStr,
+    node_root_to_root_path: ResolvedVc<RcStr>,
     environment: ResolvedVc<Environment>,
     module_id_strategy: ResolvedVc<Box<dyn ModuleIdStrategy>>,
     turbo_minify: Vc<bool>,
@@ -304,7 +304,7 @@ pub async fn get_edge_chunking_context(
     let mut builder = BrowserChunkingContext::builder(
         root_path,
         output_root,
-        node_root_to_root_path,
+        node_root_to_root_path.owned().await?,
         output_root,
         output_root.join(rcstr!("chunks")).to_resolved().await?,
         output_root.join(rcstr!("assets")).to_resolved().await?,

filename: turbopack/crates/turbopack-browser/src/chunking_context.rs
patch: @@ -166,7 +166,7 @@ impl BrowserChunkingContextBuilder {
     }
 
     pub fn build(self) -> Vc<BrowserChunkingContext> {
-        BrowserChunkingContext::new(self.chunking_context)
+        BrowserChunkingContext::cell(self.chunking_context)
     }
 }
 
@@ -302,11 +302,6 @@ impl BrowserChunkingContext {
 
 #[turbo_tasks::value_impl]
 impl BrowserChunkingContext {
-    #[turbo_tasks::function]
-    fn new(this: BrowserChunkingContext) -> Vc<Self> {
-        this.cell()
-    }
-
     #[turbo_tasks::function]
     fn generate_evaluate_chunk(
         self: Vc<Self>,

filename: turbopack/crates/turbopack-nodejs/src/chunking_context.rs
patch: @@ -96,7 +96,7 @@ impl NodeJsChunkingContextBuilder {
 
     /// Builds the chunking context.
     pub fn build(self) -> Vc<NodeJsChunkingContext> {
-        NodeJsChunkingContext::new(self.chunking_context)
+        NodeJsChunkingContext::cell(self.chunking_context)
     }
 }
 
@@ -199,11 +199,6 @@ impl NodeJsChunkingContext {
 
 #[turbo_tasks::value_impl]
 impl NodeJsChunkingContext {
-    #[turbo_tasks::function]
-    fn new(this: NodeJsChunkingContext) -> Vc<Self> {
-        this.cell()
-    }
-
     #[turbo_tasks::function]
     async fn generate_chunk(
         self: Vc<Self>,