Repository: vercel/next.js
Pull request: Turbopack Build: Fix edge _document test

## What?

Currently there's a specific case when you set `runtime: 'experimental-edge'` for `_document.js` or `_app.js` where we incorrectly write a bundle that is wrapped with the route handling code to disk. This in turn causes `_document.js` to break during prerendering. Seems no users ran into this one yet since it was experimental. This change ensures that we always write the module code for _app / _document instead. This has no negative effect on edge runtime modules because those include the direct imports for _app / _document already in the single route module.

Closes PACK-4690

Changed files:
filename: crates/next-api/src/pages.rs
patch: @@ -907,36 +907,39 @@ impl PageEndpoint {
             .module();
 
         let config = parse_config_from_source(ssr_module, NextRuntime::default()).await?;
-        Ok(if config.runtime == NextRuntime::Edge {
-            let modules = create_page_ssr_entry_module(
-                *this.pathname,
-                reference_type,
-                project_root,
-                Vc::upcast(edge_module_context),
-                self.source(),
-                *this.original_name,
-                *this.pages_structure,
-                config.runtime,
-                this.pages_project.project().next_config(),
-            )
-            .await?;
-
-            InternalSsrChunkModule {
-                ssr_module: modules.ssr_module,
-                app_module: modules.app_module,
-                document_module: modules.document_module,
-                runtime: config.runtime,
-            }
-        } else {
-            let pathname = &**this.pathname.await?;
+        let pathname = &**this.pathname.await?;
 
+        Ok(
             // `/_app` and `/_document` never get rendered directly so they don't need to be
-            // wrapped in the route module.
+            // wrapped in the route module, and don't need to be handled as edge runtime as the
+            // rendering for edge is part of the page bundle.
             if pathname == "/_app" || pathname == "/_document" {
                 InternalSsrChunkModule {
                     ssr_module: ssr_module.to_resolved().await?,
                     app_module: None,
                     document_module: None,
+                    // /_app and /_document are always rendered for Node.js for this case. For edge
+                    // they're included in the page bundle.
+                    runtime: NextRuntime::NodeJs,
+                }
+            } else if config.runtime == NextRuntime::Edge {
+                let modules = create_page_ssr_entry_module(
+                    *this.pathname,
+                    reference_type,
+                    project_root,
+                    Vc::upcast(edge_module_context),
+                    self.source(),
+                    *this.original_name,
+                    *this.pages_structure,
+                    config.runtime,
+                    this.pages_project.project().next_config(),
+                )
+                .await?;
+
+                InternalSsrChunkModule {
+                    ssr_module: modules.ssr_module,
+                    app_module: modules.app_module,
+                    document_module: modules.document_module,
                     runtime: config.runtime,
                 }
             } else {
@@ -959,8 +962,8 @@ impl PageEndpoint {
                     runtime: config.runtime,
                 }
             }
-        }
-        .cell())
+            .cell(),
+        )
     }
 
     #[turbo_tasks::function]

filename: test/turbopack-build-tests-manifest.json
patch: @@ -6544,10 +6544,10 @@
     "runtimeError": false
   },
   "test/e2e/edge-pages-support/edge-document.test.ts": {
-    "passed": [],
-    "failed": [
+    "passed": [
       "edge render - custom _document with edge runtime should render page properly"
     ],
+    "failed": [],
     "pending": [],
     "flakey": [],
     "runtimeError": false