Skip to content

Commit 99293d5

Browse files
committed
Implements module preinitialization for SSR when using turbopack
1 parent a8021cc commit 99293d5

File tree

15 files changed

+188
-37
lines changed

15 files changed

+188
-37
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/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
}
@@ -487,11 +501,13 @@ async fn insert_next_server_special_aliases(
487501
app_dir,
488502
match runtime {
489503
NextRuntime::Edge => {
490-
"next/dist/compiled/react-server-dom-webpack/client.edge"
504+
"next/dist/compiled/react-server-dom-turbopack/client.edge"
491505
}
506+
// When we access the runtime we still use the webpack name. The runtime
507+
// itself will substitute in the turbopack variant
492508
NextRuntime::NodeJs => {
493509
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
494-
react-server-dom-webpack-client-edge"
510+
react-server-dom-turbopack-client-edge"
495511
}
496512
},
497513
),
@@ -505,11 +521,13 @@ async fn insert_next_server_special_aliases(
505521
app_dir,
506522
match runtime {
507523
NextRuntime::Edge => {
508-
"next/dist/compiled/react-server-dom-webpack/client.edge"
524+
"next/dist/compiled/react-server-dom-turbopack/client.edge"
509525
}
526+
// When we access the runtime we still use the webpack name. The runtime
527+
// itself will substitute in the turbopack variant
510528
NextRuntime::NodeJs => {
511529
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
512-
react-server-dom-webpack-client-edge"
530+
react-server-dom-turbopack-client-edge"
513531
}
514532
},
515533
),
@@ -580,6 +598,14 @@ async fn insert_next_server_special_aliases(
580598
},
581599
),
582600
);
601+
import_map.insert_exact_alias(
602+
"server-only",
603+
request_to_import_mapping(app_dir, "next/dist/compiled/server-only"),
604+
);
605+
import_map.insert_exact_alias(
606+
"client-only",
607+
request_to_import_mapping(app_dir, "next/dist/compiled/client-only"),
608+
);
583609
import_map.insert_exact_alias(
584610
"react",
585611
request_to_import_mapping(
@@ -610,11 +636,13 @@ async fn insert_next_server_special_aliases(
610636
app_dir,
611637
match runtime {
612638
NextRuntime::Edge => {
613-
"next/dist/compiled/react-server-dom-webpack/server.edge"
639+
"next/dist/compiled/react-server-dom-turbopack/server.edge"
614640
}
641+
// When we access the runtime we still use the webpack name. The runtime
642+
// itself will substitute in the turbopack variant
615643
NextRuntime::NodeJs => {
616644
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
617-
react-server-dom-webpack-server-edge"
645+
react-server-dom-turbopack-server-edge"
618646
}
619647
},
620648
),
@@ -625,11 +653,13 @@ async fn insert_next_server_special_aliases(
625653
app_dir,
626654
match runtime {
627655
NextRuntime::Edge => {
628-
"next/dist/compiled/react-server-dom-webpack/server.node"
656+
"next/dist/compiled/react-server-dom-turbopack/server.node"
629657
}
658+
// When we access the runtime we still use the webpack name. The runtime
659+
// itself will substitute in the turbopack variant
630660
NextRuntime::NodeJs => {
631661
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
632-
react-server-dom-webpack-server-node"
662+
react-server-dom-turbopack-server-node"
633663
}
634664
},
635665
),

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
Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,59 @@
11
import * as React from 'react'
2+
23
import * as ReactDOM from 'react-dom/server-rendering-stub'
34

45
// eslint-disable-next-line import/no-extraneous-dependencies
56
import * as ReactDOMServerEdge from 'react-dom/server.edge'
67
// eslint-disable-next-line import/no-extraneous-dependencies
7-
import * as ReactServerDOMWebpackClientEdge from 'react-server-dom-webpack/client.edge'
88

9-
export { React, ReactDOM, ReactDOMServerEdge, ReactServerDOMWebpackClientEdge }
9+
function getAltProxyForBindingsDEV(
10+
type: 'Turbopack' | 'Webpack',
11+
pkg:
12+
| 'react-server-dom-turbopack/client.edge'
13+
| 'react-server-dom-webpack/client.edge'
14+
) {
15+
if (process.env.NODE_ENV === 'development') {
16+
const altType = type === 'Turbopack' ? 'Webpack' : 'Turbopack'
17+
const altPkg = pkg.replace(new RegExp(type, 'gi'), altType.toLowerCase())
18+
19+
return new Proxy(
20+
{},
21+
{
22+
get(_, prop: string) {
23+
throw new Error(
24+
`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.`
25+
)
26+
},
27+
}
28+
)
29+
}
30+
}
31+
32+
let ReactServerDOMTurbopackClientEdge, ReactServerDOMWebpackClientEdge
33+
if (process.env.TURBOPACK) {
34+
// eslint-disable-next-line import/no-extraneous-dependencies
35+
ReactServerDOMTurbopackClientEdge = require('react-server-dom-turbopack/client.edge')
36+
if (process.env.NODE_ENV === 'development') {
37+
ReactServerDOMWebpackClientEdge = getAltProxyForBindingsDEV(
38+
'Turbopack',
39+
'react-server-dom-turbopack/client.edge'
40+
)
41+
}
42+
} else {
43+
// eslint-disable-next-line import/no-extraneous-dependencies
44+
ReactServerDOMWebpackClientEdge = require('react-server-dom-webpack/client.edge')
45+
if (process.env.NODE_ENV === 'development') {
46+
ReactServerDOMTurbopackClientEdge = getAltProxyForBindingsDEV(
47+
'Webpack',
48+
'react-server-dom-webpack/client.edge'
49+
)
50+
}
51+
}
52+
53+
export {
54+
React,
55+
ReactDOM,
56+
ReactDOMServerEdge,
57+
ReactServerDOMTurbopackClientEdge,
58+
ReactServerDOMWebpackClientEdge,
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = require('../../module.compiled').vendored[
2+
'react-ssr'
3+
].ReactServerDOMTurbopackClientEdge

packages/next/types/misc.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ declare module 'next/dist/compiled/react-server-dom-webpack/client.edge'
1515
declare module 'next/dist/compiled/react-server-dom-webpack/client.browser'
1616
declare module 'next/dist/compiled/react-server-dom-webpack/server.browser'
1717
declare module 'next/dist/compiled/react-server-dom-webpack/server.edge'
18+
declare module 'next/dist/compiled/react-server-dom-turbopack/client'
19+
declare module 'next/dist/compiled/react-server-dom-turbopack/client.edge'
20+
declare module 'next/dist/compiled/react-server-dom-turbopack/client.browser'
21+
declare module 'next/dist/compiled/react-server-dom-turbopack/server.browser'
22+
declare module 'next/dist/compiled/react-server-dom-turbopack/server.edge'
1823
declare module 'next/dist/client/app-call-server'
1924
declare module 'next/dist/compiled/react-dom/server'
2025
declare module 'next/dist/compiled/react-dom/server.edge'

packages/next/webpack.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ function makeAppAliases(reactChannel = '') {
3232
'react-dom/server$': `next/dist/compiled/react-dom${reactChannel}/server`,
3333
'react-dom/server.edge$': `next/dist/compiled/react-dom${reactChannel}/server.edge`,
3434
'react-dom/server.browser$': `next/dist/compiled/react-dom${reactChannel}/server.browser`,
35+
'react-server-dom-turbopack/client$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/client`,
36+
'react-server-dom-turbopack/client.edge$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/client.edge`,
37+
'react-server-dom-turbopack/server.edge$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/server.edge`,
38+
'react-server-dom-turbopack/server.node$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/server.node`,
3539
'react-server-dom-webpack/client$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/client`,
3640
'react-server-dom-webpack/client.edge$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/client.edge`,
3741
'react-server-dom-webpack/server.edge$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/server.edge`,

0 commit comments

Comments
 (0)