Repository: vercel/next.js
Pull request: Turbopack: leave `chunks` in `rscModuleMapping` empty

Previously, `clientReferenceManifest.rscModuleMapping.*.chunks` would list the RSC entry, such as `server/app/encryption/page.js` which contains
```js
const CHUNK_PUBLIC_PATH = "server/app/encryption/page.js";
const runtime = require("../../chunks/ssr/[turbopack]_runtime.js");
runtime.loadChunk("server/chunks/ssr/[root-of-the-server]__a810eacb._.js");
runtime.loadChunk("server/chunks/ssr/_7a4bd82c._.js");
runtime.loadChunk("server/chunks/ssr/test_e2e_app-dir_actions_app_not-found_b8caa540.js");
runtime.loadChunk("server/chunks/ssr/packages_next_dist_client_components_1d957a03._.js");
runtime.loadChunk("server/chunks/ssr/packages_next_dist_client_components_unauthorized-error_4ad694c5.js");
runtime.loadChunk("server/chunks/ssr/_0aa93936._.js");
runtime.getOrInstantiateRuntimeModule("[project]/test/e2e/app-dir/actions/.next-internal/server/app/encryption/page/actions.js { ACTIONS_MODULE0 => \"[project]/test/e2e/app-dir/actions/app/encryption/page.js [app-rsc] (ecmascript)\" } [app-rsc] (server actions loader, ecmascript)", CHUNK_PUBLIC_PATH);
runtime.getOrInstantiateRuntimeModule("[project]/packages/next/dist/esm/build/templates/app-page.js??page=/encryption/page { MODULE_0 => \"[project]/test/e2e/app-dir/actions/app/layout.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_1 => \"[project]/test/e2e/app-dir/actions/app/not-found.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_2 => \"[project]/packages/next/dist/client/components/forbidden-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_3 => \"[project]/packages/next/dist/client/components/unauthorized-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_4 => \"[project]/test/e2e/app-dir/actions/app/encryption/page.js [app-rsc] (ecmascript, Next.js Server Component)\" } [app-rsc] (ecmascript)", CHUNK_PUBLIC_PATH);
module.exports = runtime.getOrInstantiateRuntimeModule("[project]/packages/next/dist/esm/build/templates/app-page.js??page=/encryption/page { MODULE_0 => \"[project]/test/e2e/app-dir/actions/app/layout.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_1 => \"[project]/test/e2e/app-dir/actions/app/not-found.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_2 => \"[project]/packages/next/dist/client/components/forbidden-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_3 => \"[project]/packages/next/dist/client/components/unauthorized-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_4 => \"[project]/test/e2e/app-dir/actions/app/encryption/page.js [app-rsc] (ecmascript, Next.js Server Component)\" } [app-rsc] (ecmascript)", CHUNK_PUBLIC_PATH).exports;
```

The problem is that this chunk (Turbopack calls them "entry chunk") exports some entry point, as opposed to the usual chunk which does `module.exports = {19285: function(){}, ...}` to export the module factories (called an "evaluated chunk")

If you use `__turbopack_load__` to load an entry chunk, stuff breaks because you end up with the entry module's exports in the module factory map.


Hendrik confirmed that Webpack also doesn't specify any chunks in here, they are already loaded anyway. Then this case of `__turbopack_load__`ing an entry chunk never occurs.

Closes PACK-4665

Changed files:
filename: crates/next-api/src/app.rs
patch: @@ -1459,7 +1459,6 @@ impl AppEndpoint {
                     entry_name: app_entry.original_name.clone(),
                     client_references,
                     client_references_chunks,
-                    rsc_app_entry_chunks: app_entry_chunks,
                     client_chunking_context,
                     ssr_chunking_context,
                     async_module_info: module_graphs.full.async_module_info().to_resolved().await?,

filename: crates/next-core/src/next_manifests/client_reference_manifest.rs
patch: @@ -15,7 +15,7 @@ use turbopack_core::{
     asset::{Asset, AssetContent},
     chunk::{ChunkingContext, ModuleChunkItemIdExt, ModuleId as TurbopackModuleId},
     module_graph::async_module_info::AsyncModulesInfo,
-    output::{OutputAsset, OutputAssets},
+    output::OutputAsset,
     virtual_output::VirtualOutputAsset,
 };
 use turbopack_ecmascript::utils::StringifyJs;
@@ -37,7 +37,6 @@ pub struct ClientReferenceManifestOptions {
     pub entry_name: RcStr,
     pub client_references: ResolvedVc<ClientReferenceGraphResult>,
     pub client_references_chunks: ResolvedVc<ClientReferencesChunks>,
-    pub rsc_app_entry_chunks: ResolvedVc<OutputAssets>,
     pub client_chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
     pub ssr_chunking_context: Option<ResolvedVc<Box<dyn ChunkingContext>>>,
     pub async_module_info: ResolvedVc<AsyncModulesInfo>,
@@ -58,7 +57,6 @@ impl ClientReferenceManifest {
             entry_name,
             client_references,
             client_references_chunks,
-            rsc_app_entry_chunks,
             client_chunking_context,
             ssr_chunking_context,
             async_module_info,
@@ -100,7 +98,6 @@ impl ClientReferenceManifest {
             } = &*client_references_chunks.await?;
             let client_relative_path = &*client_relative_path.await?;
             let node_root_ref = &*node_root.await?;
-            let rsc_app_entry_chunks = &*rsc_app_entry_chunks.await?;
 
             let client_references_ecmascript = client_references
                 .await?
@@ -167,10 +164,6 @@ impl ClientReferenceManifest {
                 ResolvedVc<Box<dyn OutputAsset>>,
                 ReadRef<FileSystemPath>,
             > = FxHashMap::default();
-            let mut rsc_chunk_path_cache: FxHashMap<
-                ResolvedVc<Box<dyn OutputAsset>>,
-                ReadRef<FileSystemPath>,
-            > = FxHashMap::default();
 
             for (client_reference_module, client_reference_module_ref) in
                 client_references_ecmascript
@@ -266,32 +259,10 @@ impl ClientReferenceManifest {
                         (Vec::new(), false)
                     };
 
-                    let (rsc_chunks_paths, rsc_is_async) = if runtime == NextRuntime::Edge {
-                        // the chunks get added to the middleware-manifest.json instead
-                        // of this file because the
-                        // edge runtime doesn't support dynamically
-                        // loading chunks.
-                        (Vec::new(), false)
+                    let rsc_is_async = if runtime == NextRuntime::Edge {
+                        false
                     } else {
-                        let rsc_chunks_paths = cached_chunk_paths(
-                            &mut rsc_chunk_path_cache,
-                            rsc_app_entry_chunks.iter().copied(),
-                        )
-                        .await?;
-
-                        let chunk_paths = rsc_chunks_paths
-                            .filter_map(|(_, chunk_path)| {
-                                node_root_ref
-                                    .get_path_to(&chunk_path)
-                                    .map(ToString::to_string)
-                            })
-                            .map(RcStr::from)
-                            .collect::<Vec<_>>();
-
-                        let is_async =
-                            async_modules.contains(&ResolvedVc::upcast(client_reference_module));
-
-                        (chunk_paths, is_async)
+                        async_modules.contains(&ResolvedVc::upcast(client_reference_module))
                     };
 
                     entry_manifest.client_modules.module_exports.insert(
@@ -326,7 +297,7 @@ impl ClientReferenceManifest {
                         ManifestNodeEntry {
                             name: "*".into(),
                             id: (&*rsc_chunk_item_id).into(),
-                            chunks: rsc_chunks_paths,
+                            chunks: vec![],
                             r#async: rsc_is_async,
                         },
                     );