Skip to content

Commit 05d9e37

Browse files
committed
[turbopack] Add chunk_group_bootstrap_params and the chunk-loading global to the build manifest
1 parent f6af595 commit 05d9e37

5 files changed

Lines changed: 100 additions & 25 deletions

File tree

crates/next-api/src/app.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,26 +1301,30 @@ impl AppEndpoint {
13011301
.await?;
13021302

13031303
// We only need the client runtime entries for pages not for Route Handlers
1304-
let (availability_info, client_shared_chunks) = if is_app_page {
1305-
let client_shared_chunk_group = get_app_client_shared_chunk_group(
1306-
AssetIdent::from_path(project.project_path().owned().await?)
1307-
.with_modifier(rcstr!("client-shared-chunks"))
1308-
.into_vc(),
1309-
this.app_project.client_runtime_entries(),
1310-
*module_graphs.full,
1311-
*client_chunking_context,
1312-
);
1304+
let (availability_info, client_shared_chunks, client_chunk_group_bootstrap_params) =
1305+
if is_app_page {
1306+
let client_shared_chunk_group = get_app_client_shared_chunk_group(
1307+
AssetIdent::from_path(project.project_path().owned().await?)
1308+
.with_modifier(rcstr!("client-shared-chunks"))
1309+
.into_vc(),
1310+
this.app_project.client_runtime_entries(),
1311+
*module_graphs.full,
1312+
*client_chunking_context,
1313+
);
13131314

1314-
client_assets.extend(client_shared_chunk_group.all_assets().await?);
1315+
client_assets.extend(client_shared_chunk_group.all_assets().await?);
13151316

1316-
let client_shared_chunk_group = client_shared_chunk_group.await?;
1317-
(
1318-
client_shared_chunk_group.availability_info,
1319-
client_shared_chunk_group.assets.owned().await?,
1320-
)
1321-
} else {
1322-
(AvailabilityInfo::root(), vec![])
1323-
};
1317+
let client_shared_chunk_group = client_shared_chunk_group.await?;
1318+
(
1319+
client_shared_chunk_group.availability_info,
1320+
client_shared_chunk_group.assets.owned().await?,
1321+
client_shared_chunk_group
1322+
.chunk_group_bootstrap_params
1323+
.clone(),
1324+
)
1325+
} else {
1326+
(AvailabilityInfo::root(), vec![], None)
1327+
};
13241328

13251329
let client_references_chunks = get_app_client_references_chunks(
13261330
*client_references,
@@ -1423,6 +1427,12 @@ impl AppEndpoint {
14231427
m.insert(app_entry.original_name.clone(), page_hmr_chunks);
14241428
m
14251429
};
1430+
let chunk_loading_global = (*project
1431+
.next_config()
1432+
.turbopack_chunk_loading_global()
1433+
.await?)
1434+
.clone()
1435+
.unwrap_or_else(|| rcstr!("TURBOPACK"));
14261436
let build_manifest = BuildManifest {
14271437
output_path: node_root.join(&format!(
14281438
"server/app{manifest_path_prefix}/build-manifest.json",
@@ -1432,6 +1442,14 @@ impl AppEndpoint {
14321442
root_main_files: client_shared_chunks,
14331443
polyfill_files: polyfill_output_asset.into_iter().collect(),
14341444
root_main_files_per_page,
1445+
pages_chunk_group_bootstrap_params: client_chunk_group_bootstrap_params
1446+
.map(|params| {
1447+
let mut m = FxIndexMap::default();
1448+
m.insert(app_entry.original_name.clone(), params);
1449+
m
1450+
})
1451+
.unwrap_or_default(),
1452+
chunk_loading_global,
14351453
};
14361454
server_assets.insert(ResolvedVc::upcast(build_manifest.resolved_cell()));
14371455
}

crates/next-api/src/pages.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,9 @@ impl PageEndpoint {
12351235
async fn build_manifest(
12361236
&self,
12371237
client_chunks: ResolvedVc<OutputAssets>,
1238+
// The inline chunk group bootstrap params for this page, when the client chunking
1239+
// context inlines the bootstrap instead of emitting a per-route chunk.
1240+
chunk_group_bootstrap_params: Option<RcStr>,
12381241
) -> Result<Vc<Box<dyn OutputAsset>>> {
12391242
let node_root = self.pages_project.project().node_root().owned().await?;
12401243
let client_relative_path = self
@@ -1246,11 +1249,27 @@ impl PageEndpoint {
12461249

12471250
// Check if we should include pages in the manifest
12481251
let pages_structure = self.pages_structure.await?;
1249-
let pages = if pages_structure.should_create_pages_entries {
1250-
fxindexmap!(self.pathname.clone() => client_chunks)
1251-
} else {
1252-
fxindexmap![] // Empty pages when no user pages should be created
1253-
};
1252+
let (pages, pages_chunk_group_bootstrap_params) =
1253+
if pages_structure.should_create_pages_entries {
1254+
(
1255+
fxindexmap!(self.pathname.clone() => client_chunks),
1256+
chunk_group_bootstrap_params
1257+
.map(|params| fxindexmap!(self.pathname.clone() => params))
1258+
.unwrap_or_default(),
1259+
)
1260+
} else {
1261+
// Empty when no user pages should be created
1262+
(fxindexmap![], fxindexmap![])
1263+
};
1264+
1265+
let chunk_loading_global = (*self
1266+
.pages_project
1267+
.project()
1268+
.next_config()
1269+
.turbopack_chunk_loading_global()
1270+
.await?)
1271+
.clone()
1272+
.unwrap_or_else(|| rcstr!("TURBOPACK"));
12541273

12551274
let manifest_path_prefix = get_asset_prefix_from_pathname(&self.pathname);
12561275
let build_manifest = BuildManifest {
@@ -1262,6 +1281,8 @@ impl PageEndpoint {
12621281
polyfill_files: Default::default(),
12631282
root_main_files: Default::default(),
12641283
root_main_files_per_page: Default::default(),
1284+
pages_chunk_group_bootstrap_params,
1285+
chunk_loading_global,
12651286
};
12661287
Ok(Vc::upcast(build_manifest.cell()))
12671288
}
@@ -1316,9 +1337,15 @@ impl PageEndpoint {
13161337
PageEndpointType::Html => {
13171338
let client_chunk_group = self.client_chunk_group();
13181339
client_assets.extend(client_chunk_group.all_assets().await?.iter().copied());
1319-
let client_chunks = *client_chunk_group.await?.assets;
1340+
let client_chunk_group_ref = client_chunk_group.await?;
1341+
let client_chunks = *client_chunk_group_ref.assets;
1342+
let chunk_group_bootstrap_params =
1343+
client_chunk_group_ref.chunk_group_bootstrap_params.clone();
13201344

1321-
let build_manifest = self.build_manifest(client_chunks).to_resolved().await?;
1345+
let build_manifest = self
1346+
.build_manifest(client_chunks, chunk_group_bootstrap_params)
1347+
.to_resolved()
1348+
.await?;
13221349
let page_loader = self.page_loader(client_chunks).to_resolved().await?;
13231350
let client_build_manifest = self
13241351
.client_build_manifest(*page_loader)

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ pub struct BuildManifest {
4040
/// page-specific scripts without polluting the shared `rootMainFiles`.
4141
#[bincode(with = "turbo_bincode::indexmap")]
4242
pub root_main_files_per_page: FxIndexMap<RcStr, Vec<ResolvedVc<Box<dyn OutputAsset>>>>,
43+
/// Per-page inline chunk group bootstrap params — the `{ otherChunks,
44+
/// runtimeModuleIds }` registration object (as JSON). Next wraps it in
45+
/// `globalThis[chunkLoadingGlobal].push(...)` itself (inline in the document for the
46+
/// initial page; in `route-loader` for client navigations). Empty when the per-route
47+
/// bootstrap is emitted as a chunk (eg. in dev).
48+
#[bincode(with = "turbo_bincode::indexmap")]
49+
pub pages_chunk_group_bootstrap_params: FxIndexMap<RcStr, RcStr>,
50+
/// The `globalThis[...]` chunk-loading global the runtime drains (default
51+
/// `"TURBOPACK"`). Needed to wrap `pages_chunk_group_bootstrap_params` client-side.
52+
pub chunk_loading_global: RcStr,
4353
}
4454

4555
#[turbo_tasks::value_impl]
@@ -101,6 +111,8 @@ impl Asset for BuildManifest {
101111
pub pages: FxIndexMap<RcStr, Vec<RcStr>>,
102112
pub amp_first_pages: Vec<RcStr>,
103113
pub root_main_files_tree: FxIndexMap<RcStr, Vec<RcStr>>,
114+
pub pages_chunk_group_bootstrap_params: FxIndexMap<RcStr, RcStr>,
115+
pub chunk_loading_global: RcStr,
104116
}
105117

106118
let pages: Vec<(RcStr, Vec<RcStr>)> = self
@@ -195,6 +207,8 @@ impl Asset for BuildManifest {
195207
polyfill_files,
196208
root_main_files,
197209
root_main_files_tree: FxIndexMap::from_iter(root_main_files_tree),
210+
pages_chunk_group_bootstrap_params: self.pages_chunk_group_bootstrap_params.clone(),
211+
chunk_loading_global: self.chunk_loading_global.clone(),
198212
..Default::default()
199213
};
200214

packages/next/src/server/get-page-files.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ export type BuildManifest = {
1414
'/_app': readonly string[]
1515
[page: string]: readonly string[]
1616
}
17+
// Per-page Turbopack chunk-group bootstrap params — the `{ otherChunks,
18+
// runtimeModuleIds }` object as a JSON string.
19+
pagesChunkGroupBootstrapParams?: { [page: string]: string }
20+
// The `globalThis[...]` chunk-loading global the runtime drains (default
21+
// "TURBOPACK"); used to wrap `pagesChunkGroupBootstrapParams`.
22+
chunkLoadingGlobal?: string
1723
}
1824

1925
export function getPageFiles(

packages/next/src/shared/lib/turbopack/manifest-loader.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ export class TurbopackManifestLoader {
417417
lowPriorityFiles,
418418
rootMainFiles: [],
419419
rootMainFilesTree: {},
420+
pagesChunkGroupBootstrapParams: {},
420421
}
421422
for (const m of manifests) {
422423
Object.assign(manifest.pages, m.pages)
@@ -426,6 +427,14 @@ export class TurbopackManifestLoader {
426427
if (m.rootMainFilesTree) {
427428
Object.assign(manifest.rootMainFilesTree!, m.rootMainFilesTree)
428429
}
430+
if (m.pagesChunkGroupBootstrapParams) {
431+
Object.assign(
432+
manifest.pagesChunkGroupBootstrapParams!,
433+
m.pagesChunkGroupBootstrapParams
434+
)
435+
}
436+
if (m.chunkLoadingGlobal)
437+
manifest.chunkLoadingGlobal = m.chunkLoadingGlobal
429438
}
430439
manifest.pages = sortObjectByKey(manifest.pages) as BuildManifest['pages']
431440
return manifest
@@ -575,6 +584,7 @@ export class TurbopackManifestLoader {
575584
rewrites,
576585
sortedPageKeys
577586
)
587+
578588
const clientBuildManifestJs = `self.__BUILD_MANIFEST = ${JSON.stringify(
579589
clientBuildManifest,
580590
null,

0 commit comments

Comments
 (0)