Skip to content

Commit e92e687

Browse files
committed
Implements module preinitialization for SSR when using turbopack
1 parent 3391b48 commit e92e687

21 files changed

+192
-68
lines changed

packages/next-swc/crates/next-api/src/app.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ impl AppProject {
212212
"next-dynamic".to_string(),
213213
Vc::upcast(NextDynamicTransition::new(self.client_transition())),
214214
),
215+
("next-ssr".to_string(), Vc::upcast(self.ssr_transition())),
215216
]
216217
.into_iter()
217218
.collect();

packages/next-swc/crates/next-core/js/src/entry/app-renderer.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { PassThrough } from 'node:stream'
1818
import entry from 'APP_ENTRY'
1919
import BOOTSTRAP from 'APP_BOOTSTRAP'
2020
import { createServerResponse } from '../internal/http'
21-
import { createManifests, installRequireAndChunkLoad } from './app/manifest'
21+
import { createManifests } from './app/manifest'
2222
import { join } from 'node:path'
2323
import { nodeFs } from 'next/dist/server/lib/node-fs-methods'
2424
import { IncrementalCache } from 'next/dist/server/lib/incremental-cache'
@@ -27,8 +27,6 @@ const {
2727
renderToHTMLOrFlight,
2828
} = require('next/dist/compiled/next-server/app-page.runtime.dev')
2929

30-
installRequireAndChunkLoad()
31-
3230
const MIME_TEXT_HTML_UTF8 = 'text/html; charset=utf-8'
3331

3432
startOperationStreamHandler(async (renderData: RenderData, respond) => {
@@ -92,10 +90,6 @@ async function runOperation(renderData: RenderData) {
9290
},
9391
ComponentMod: {
9492
...entry,
95-
__next_app__: {
96-
require: __next_require__,
97-
loadChunk: __next_chunk_load__,
98-
},
9993
pages: ['page.js'],
10094
},
10195
incrementalCache: new IncrementalCache({

packages/next-swc/crates/next-core/js/src/entry/app/edge-page-bootstrap.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ import { renderToHTMLOrFlight } from 'next/dist/server/app-render/app-render'
55
;('TURBOPACK { chunking-type: isolatedParallel }')
66
import entry from 'APP_ENTRY'
77
import BOOTSTRAP from 'APP_BOOTSTRAP'
8-
import { createManifests, installRequireAndChunkLoad } from './manifest'
8+
import { createManifests } from './manifest'
99
import type { NextRequest, NextFetchEvent } from 'next/server'
1010
import type { RenderOpts } from 'next/dist/server/app-render/types'
1111
import type { ParsedUrlQuery } from 'querystring'
1212

13-
installRequireAndChunkLoad()
14-
1513
// avoid limiting stack traces to 10 lines
1614
Error.stackTraceLimit = 100
1715

@@ -43,10 +41,6 @@ async function render(request: NextRequest, event: NextFetchEvent) {
4341
},
4442
ComponentMod: {
4543
...entry,
46-
__next_app__: {
47-
require: __next_require__,
48-
loadChunk: __next_chunk_load__,
49-
},
5044
pages: ['page.js'],
5145
},
5246
clientReferenceManifest,

packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import ReactDOMClient from 'react-dom/client'
22
import React, { use } from 'react'
33
import type { ReactElement } from 'react'
44
import { version } from 'next/package.json'
5-
import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-webpack/client'
5+
import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-turbopack/client'
66
import { callServer } from 'next/dist/client/app-call-server'
77
import { linkGc } from 'next/dist/client/app-link-gc'
88

@@ -19,12 +19,6 @@ window.next = {
1919
appDir: true,
2020
}
2121

22-
globalThis.__next_require__ = (data) => {
23-
const [client_id] = JSON.parse(data)
24-
return __turbopack_require__(client_id)
25-
}
26-
globalThis.__next_chunk_load__ = __turbopack_load__
27-
2822
const appElement = document
2923

3024
const getCacheKey = () => {

packages/next-swc/crates/next-core/js/src/entry/app/manifest.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,3 @@ export function createManifests() {
114114

115115
return { clientReferenceManifest }
116116
}
117-
118-
export function installRequireAndChunkLoad() {
119-
globalThis.__next_require__ = (data) => {
120-
const [, , ssr_id] = JSON.parse(data)
121-
return __turbopack_require__(ssr_id)
122-
}
123-
globalThis.__next_chunk_load__ = () => Promise.resolve()
124-
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
declare module 'next/dist/compiled/react-server-dom-webpack/client'
2+
declare module 'next/dist/compiled/react-server-dom-turbopack/client'

packages/next-swc/crates/next-core/js/types/globals.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ declare global {
88
var __webpack_public_path__: string | undefined
99
var __DEV_MIDDLEWARE_MATCHERS: any[]
1010

11-
var __next_require__: (id: string) => any
12-
var __next_chunk_load__: (id: string) => Promise
1311
var __next_f: (
1412
| [isBootStrap: 0]
1513
| [isNotBootstrap: 1, responsePartial: string]

packages/next-swc/crates/next-core/src/next_import_map.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ pub async fn get_next_client_import_map(
8989
);
9090
}
9191
ClientContextType::App { app_dir } => {
92+
import_map.insert_exact_alias(
93+
"server-only",
94+
request_to_import_mapping(app_dir, "next/dist/compiled/server-only"),
95+
);
96+
import_map.insert_exact_alias(
97+
"client-only",
98+
request_to_import_mapping(app_dir, "next/dist/compiled/client-only"),
99+
);
92100
import_map.insert_exact_alias(
93101
"react",
94102
request_to_import_mapping(app_dir, "next/dist/compiled/react"),
@@ -107,7 +115,10 @@ pub async fn get_next_client_import_map(
107115
);
108116
import_map.insert_wildcard_alias(
109117
"react-server-dom-webpack/",
110-
request_to_import_mapping(app_dir, "next/dist/compiled/react-server-dom-webpack/*"),
118+
request_to_import_mapping(
119+
app_dir,
120+
"next/dist/compiled/react-server-dom-turbopack/*",
121+
),
111122
);
112123
import_map.insert_exact_alias(
113124
"next/head",
@@ -238,7 +249,10 @@ pub async fn get_next_server_import_map(
238249
import_map.insert_wildcard_alias("react-dom/", external);
239250
import_map.insert_exact_alias("styled-jsx", external);
240251
import_map.insert_wildcard_alias("styled-jsx/", external);
241-
import_map.insert_wildcard_alias("react-server-dom-webpack/", external);
252+
import_map.insert_exact_alias(
253+
"react-server-dom-webpack/",
254+
ImportMapping::External(Some("react-server-dom-turbopack".into())).cell(),
255+
);
242256
// TODO: we should not bundle next/dist/build/utils in the pages renderer at all
243257
import_map.insert_wildcard_alias("next/dist/build/utils", external);
244258
}
@@ -498,11 +512,13 @@ async fn insert_next_server_special_aliases(
498512
app_dir,
499513
match runtime {
500514
NextRuntime::Edge => {
501-
"next/dist/compiled/react-server-dom-webpack/client.edge"
515+
"next/dist/compiled/react-server-dom-turbopack/client.edge"
502516
}
517+
// When we access the runtime we still use the webpack name. The runtime
518+
// itself will substitute in the turbopack variant
503519
NextRuntime::NodeJs => {
504520
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
505-
react-server-dom-webpack-client-edge"
521+
react-server-dom-turbopack-client-edge"
506522
}
507523
},
508524
),
@@ -516,11 +532,13 @@ async fn insert_next_server_special_aliases(
516532
app_dir,
517533
match runtime {
518534
NextRuntime::Edge => {
519-
"next/dist/compiled/react-server-dom-webpack/client.edge"
535+
"next/dist/compiled/react-server-dom-turbopack/client.edge"
520536
}
537+
// When we access the runtime we still use the webpack name. The runtime
538+
// itself will substitute in the turbopack variant
521539
NextRuntime::NodeJs => {
522540
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
523-
react-server-dom-webpack-client-edge"
541+
react-server-dom-turbopack-client-edge"
524542
}
525543
},
526544
),
@@ -591,6 +609,14 @@ async fn insert_next_server_special_aliases(
591609
},
592610
),
593611
);
612+
import_map.insert_exact_alias(
613+
"server-only",
614+
request_to_import_mapping(app_dir, "next/dist/compiled/server-only"),
615+
);
616+
import_map.insert_exact_alias(
617+
"client-only",
618+
request_to_import_mapping(app_dir, "next/dist/compiled/client-only"),
619+
);
594620
import_map.insert_exact_alias(
595621
"react",
596622
request_to_import_mapping(
@@ -621,11 +647,13 @@ async fn insert_next_server_special_aliases(
621647
app_dir,
622648
match runtime {
623649
NextRuntime::Edge => {
624-
"next/dist/compiled/react-server-dom-webpack/server.edge"
650+
"next/dist/compiled/react-server-dom-turbopack/server.edge"
625651
}
652+
// When we access the runtime we still use the webpack name. The runtime
653+
// itself will substitute in the turbopack variant
626654
NextRuntime::NodeJs => {
627655
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
628-
react-server-dom-webpack-server-edge"
656+
react-server-dom-turbopack-server-edge"
629657
}
630658
},
631659
),
@@ -636,11 +664,13 @@ async fn insert_next_server_special_aliases(
636664
app_dir,
637665
match runtime {
638666
NextRuntime::Edge => {
639-
"next/dist/compiled/react-server-dom-webpack/server.node"
667+
"next/dist/compiled/react-server-dom-turbopack/server.node"
640668
}
669+
// When we access the runtime we still use the webpack name. The runtime
670+
// itself will substitute in the turbopack variant
641671
NextRuntime::NodeJs => {
642672
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
643-
react-server-dom-webpack-server-node"
673+
react-server-dom-turbopack-server-node"
644674
}
645675
},
646676
),

packages/next-swc/crates/next-core/src/next_manifests/client_reference_manifest.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ impl ClientReferenceManifest {
3232
ssr_chunking_context: Vc<Box<dyn EcmascriptChunkingContext>>,
3333
) -> Result<Vc<Box<dyn OutputAsset>>> {
3434
let mut entry_manifest: ClientReferenceManifest = Default::default();
35+
entry_manifest.module_loading.prefix = "/_next/".to_string();
36+
entry_manifest.module_loading.cross_origin = None;
3537
let client_references_chunks = client_references_chunks.await?;
3638
let client_relative_path = client_relative_path.await?;
3739
let node_root_ref = node_root.await?;

packages/next-swc/crates/next-core/src/next_manifests/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ pub enum ActionManifestWorkerEntry {
178178
#[derive(Serialize, Default, Debug)]
179179
#[serde(rename_all = "camelCase")]
180180
pub struct ClientReferenceManifest {
181+
pub module_loading: ModuleLoading,
181182
/// Mapping of module path and export name to client module ID and required
182183
/// client chunks.
183184
pub client_modules: ManifestNode,
@@ -192,6 +193,13 @@ pub struct ClientReferenceManifest {
192193
pub entry_css_files: HashMap<String, Vec<String>>,
193194
}
194195

196+
#[derive(Serialize, Default, Debug)]
197+
#[serde(rename_all = "camelCase")]
198+
pub struct ModuleLoading {
199+
pub prefix: String,
200+
pub cross_origin: Option<String>,
201+
}
202+
195203
#[derive(Serialize, Default, Debug)]
196204
#[serde(rename_all = "camelCase")]
197205
pub struct ManifestNode {
Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +0,0 @@
1-
declare let __turbopack_require__: any
2-
3-
// @ts-expect-error
4-
process.env.__NEXT_NEW_LINK_BEHAVIOR = true
5-
6-
// eslint-disable-next-line no-undef
7-
;(self as any).__next_require__ = __turbopack_require__
8-
9-
// @ts-ignore
10-
// eslint-disable-next-line no-undef
11-
;(self as any).__next_chunk_load__ = __turbopack_load__
12-
13-
export {}

packages/next/src/client/components/react-dev-overlay/internal/helpers/group-stack-frames-by-framework.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function getFramework(
1414
if (!sourcePackage) return undefined
1515

1616
if (
17-
/^(react|react-dom|react-is|react-refresh|react-server-dom-webpack|scheduler)$/.test(
17+
/^(react|react-dom|react-is|react-refresh|react-server-dom-webpack|react-server-dom-turbopack|scheduler)$/.test(
1818
sourcePackage
1919
)
2020
) {

packages/next/src/server/app-render/entry-base-ssr.ts

Whitespace-only changes.

packages/next/src/server/app-render/ssr/index.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/next/src/server/future/route-modules/app-page/vendored/rsc/entrypoints.ts

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,75 @@ import * as React from 'react'
22

33
import * as ReactDOM from 'react-dom/server-rendering-stub'
44

5-
// eslint-disable-next-line import/no-extraneous-dependencies
6-
import * as ReactServerDOMWebpackServerNode from 'react-server-dom-webpack/server.node'
7-
// eslint-disable-next-line import/no-extraneous-dependencies
8-
import * as ReactServerDOMWebpackServerEdge from 'react-server-dom-webpack/server.edge'
5+
function getAltProxyForBindingsDEV(
6+
type: 'Turbopack' | 'Webpack',
7+
pkg:
8+
| 'react-server-dom-turbopack/server.edge'
9+
| 'react-server-dom-turbopack/server.node'
10+
| 'react-server-dom-webpack/server.edge'
11+
| 'react-server-dom-webpack/server.node'
12+
) {
13+
if (process.env.NODE_ENV === 'development') {
14+
const altType = type === 'Turbopack' ? 'Webpack' : 'Turbopack'
15+
const altPkg = pkg.replace(new RegExp(type, 'gi'), altType.toLowerCase())
16+
17+
return new Proxy(
18+
{},
19+
{
20+
get(_, prop: string) {
21+
throw new Error(
22+
`Expected to use ${type} bindings (${pkg}) for React but the current process is referencing '${prop}' from the ${altType} bindings (${altPkg}). This is likely a bug in our integration of the Next.js server runtime.`
23+
)
24+
},
25+
}
26+
)
27+
}
28+
}
29+
30+
let ReactServerDOMTurbopackServerEdge, ReactServerDOMWebpackServerEdge
31+
let ReactServerDOMTurbopackServerNode, ReactServerDOMWebpackServerNode
32+
33+
if (process.env.TURBOPACK) {
34+
// eslint-disable-next-line import/no-extraneous-dependencies
35+
ReactServerDOMTurbopackServerEdge = require('react-server-dom-turbopack/server.edge')
36+
if (process.env.NODE_ENV === 'development') {
37+
ReactServerDOMWebpackServerEdge = getAltProxyForBindingsDEV(
38+
'Turbopack',
39+
'react-server-dom-turbopack/server.edge'
40+
)
41+
}
42+
// eslint-disable-next-line import/no-extraneous-dependencies
43+
ReactServerDOMTurbopackServerNode = require('react-server-dom-turbopack/server.node')
44+
if (process.env.NODE_ENV === 'development') {
45+
ReactServerDOMWebpackServerNode = getAltProxyForBindingsDEV(
46+
'Turbopack',
47+
'react-server-dom-turbopack/server.node'
48+
)
49+
}
50+
} else {
51+
// eslint-disable-next-line import/no-extraneous-dependencies
52+
ReactServerDOMWebpackServerEdge = require('react-server-dom-webpack/server.edge')
53+
if (process.env.NODE_ENV === 'development') {
54+
ReactServerDOMTurbopackServerEdge = getAltProxyForBindingsDEV(
55+
'Webpack',
56+
'react-server-dom-webpack/server.edge'
57+
)
58+
}
59+
// eslint-disable-next-line import/no-extraneous-dependencies
60+
ReactServerDOMWebpackServerNode = require('react-server-dom-webpack/server.node')
61+
if (process.env.NODE_ENV === 'development') {
62+
ReactServerDOMTurbopackServerNode = getAltProxyForBindingsDEV(
63+
'Webpack',
64+
'react-server-dom-webpack/server.node'
65+
)
66+
}
67+
}
968

1069
export {
1170
React,
1271
ReactDOM,
13-
ReactServerDOMWebpackServerNode,
1472
ReactServerDOMWebpackServerEdge,
73+
ReactServerDOMTurbopackServerEdge,
74+
ReactServerDOMWebpackServerNode,
75+
ReactServerDOMTurbopackServerNode,
1576
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = require('../../module.compiled').vendored[
2+
'react-rsc'
3+
].ReactServerDOMTurbopackServerEdge
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = require('../../module.compiled').vendored[
2+
'react-rsc'
3+
].ReactServerDOMTurbopackServerNode

0 commit comments

Comments
 (0)