Skip to content

Commit aa59279

Browse files
authored
avoid sending modules in parent for dynamic imports (vercel/turborepo#4056)
### Description Keeps track of available modules when importing new chunk groups. Omits assets that are already available in the parent chunk group(s) when determining assets to be included in chunks. ### Testing Instructions Dynamic imports should not include modules that are already in the parent chunks <!-- When the below is checked (default) our PR bot will automatically assign labels to your PR based on the content to help the team organize and review it faster. --> - [x] Auto label fixes WEB-599
1 parent 88bacfd commit aa59279

File tree

11 files changed

+152
-173
lines changed

11 files changed

+152
-173
lines changed

crates/next-core/js/src/entry/app/server-to-client-ssr.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createProxy } from "next/dist/build/webpack/loaders/next-flight-loader/module-proxy";
22

3-
("TURBOPACK { chunking-type: parallel }");
3+
("TURBOPACK { chunking-type: isolatedParallel }");
44
// @ts-expect-error CLIENT_MODULE is provided by rust
55
import { __turbopack_module_id__ as id } from "CLIENT_MODULE";
66

crates/next-core/src/app_source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl AppRendererVc {
593593

594594
for (_, imports) in segments.iter() {
595595
for (p, identifier, chunks_identifier) in imports.values() {
596-
result += r#"("TURBOPACK { transition: next-layout-entry; chunking-type: parallel }");
596+
result += r#"("TURBOPACK { transition: next-layout-entry; chunking-type: isolatedParallel }");
597597
"#;
598598
writeln!(
599599
result,

crates/next-core/src/next_client_chunks/in_chunking_context_asset.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use anyhow::Result;
2-
use turbo_tasks::primitives::StringVc;
2+
use turbo_tasks::{primitives::StringVc, Value};
33
use turbopack::ecmascript::chunk::{
44
EcmascriptChunkItemVc, EcmascriptChunkPlaceable, EcmascriptChunkPlaceableVc, EcmascriptChunkVc,
55
EcmascriptExportsVc,
66
};
77
use turbopack_core::{
88
asset::{Asset, AssetContentVc, AssetVc},
9-
chunk::{ChunkVc, ChunkableAsset, ChunkableAssetVc, ChunkingContextVc},
9+
chunk::{
10+
availability_info::AvailabilityInfo, ChunkVc, ChunkableAsset, ChunkableAssetVc,
11+
ChunkingContextVc,
12+
},
1013
ident::AssetIdentVc,
1114
reference::AssetReferencesVc,
1215
};
@@ -43,8 +46,12 @@ impl Asset for InChunkingContextAsset {
4346
#[turbo_tasks::value_impl]
4447
impl ChunkableAsset for InChunkingContextAsset {
4548
#[turbo_tasks::function]
46-
fn as_chunk(&self, _context: ChunkingContextVc) -> ChunkVc {
47-
EcmascriptChunkVc::new(self.chunking_context, self.asset).into()
49+
fn as_chunk(
50+
&self,
51+
_context: ChunkingContextVc,
52+
availability_info: Value<AvailabilityInfo>,
53+
) -> ChunkVc {
54+
EcmascriptChunkVc::new(self.chunking_context, self.asset, availability_info).into()
4855
}
4956
}
5057

Lines changed: 49 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use anyhow::{bail, Result};
22
use indoc::formatdoc;
3-
use serde_json::Value;
4-
use turbo_tasks::{primitives::StringVc, TryJoinIterExt, ValueToString, ValueToStringVc};
3+
use turbo_tasks::{primitives::StringVc, TryJoinIterExt, Value};
54
use turbo_tasks_fs::FileSystemPathVc;
65
use turbopack::ecmascript::{
76
chunk::{
@@ -14,18 +13,15 @@ use turbopack::ecmascript::{
1413
use turbopack_core::{
1514
asset::{Asset, AssetContentVc, AssetVc},
1615
chunk::{
17-
Chunk, ChunkGroupVc, ChunkItem, ChunkItemVc, ChunkListReferenceVc, ChunkVc, ChunkableAsset,
18-
ChunkableAssetReference, ChunkableAssetReferenceVc, ChunkableAssetVc, ChunkingContext,
19-
ChunkingContextVc, ChunkingType, ChunkingTypeOptionVc,
16+
availability_info::AvailabilityInfo, Chunk, ChunkGroupReferenceVc, ChunkGroupVc, ChunkItem,
17+
ChunkItemVc, ChunkListReferenceVc, ChunkVc, ChunkableAsset, ChunkableAssetVc,
18+
ChunkingContextVc,
2019
},
2120
ident::AssetIdentVc,
22-
reference::{AssetReference, AssetReferenceVc, AssetReferencesVc},
23-
resolve::{ResolveResult, ResolveResultVc},
21+
reference::AssetReferencesVc,
2422
};
2523
use turbopack_ecmascript::utils::stringify_js_pretty;
2624

27-
use super::in_chunking_context_asset::InChunkingContextAsset;
28-
2925
#[turbo_tasks::function]
3026
fn modifier() -> StringVc {
3127
StringVc::cell("chunks".to_string())
@@ -51,16 +47,30 @@ impl Asset for WithChunksAsset {
5147
}
5248

5349
#[turbo_tasks::function]
54-
fn references(&self) -> AssetReferencesVc {
55-
unimplemented!()
50+
async fn references(self_vc: WithChunksAssetVc) -> Result<AssetReferencesVc> {
51+
let this = self_vc.await?;
52+
let chunk_group = self_vc.chunk_group();
53+
Ok(AssetReferencesVc::cell(vec![
54+
ChunkGroupReferenceVc::new(chunk_group).into(),
55+
ChunkListReferenceVc::new(this.server_root, chunk_group).into(),
56+
]))
5657
}
5758
}
5859

5960
#[turbo_tasks::value_impl]
6061
impl ChunkableAsset for WithChunksAsset {
6162
#[turbo_tasks::function]
62-
fn as_chunk(self_vc: WithChunksAssetVc, context: ChunkingContextVc) -> ChunkVc {
63-
EcmascriptChunkVc::new(context, self_vc.as_ecmascript_chunk_placeable()).into()
63+
fn as_chunk(
64+
self_vc: WithChunksAssetVc,
65+
context: ChunkingContextVc,
66+
availability_info: Value<AvailabilityInfo>,
67+
) -> ChunkVc {
68+
EcmascriptChunkVc::new(
69+
context,
70+
self_vc.as_ecmascript_chunk_placeable(),
71+
availability_info,
72+
)
73+
.into()
6474
}
6575
}
6676

@@ -71,10 +81,8 @@ impl EcmascriptChunkPlaceable for WithChunksAsset {
7181
self_vc: WithChunksAssetVc,
7282
context: ChunkingContextVc,
7383
) -> Result<EcmascriptChunkItemVc> {
74-
let this = self_vc.await?;
7584
Ok(WithChunksChunkItem {
7685
context,
77-
inner_context: this.chunking_context,
7886
inner: self_vc,
7987
}
8088
.cell()
@@ -88,32 +96,27 @@ impl EcmascriptChunkPlaceable for WithChunksAsset {
8896
}
8997
}
9098

91-
#[turbo_tasks::value]
92-
struct WithChunksChunkItem {
93-
context: ChunkingContextVc,
94-
inner_context: ChunkingContextVc,
95-
inner: WithChunksAssetVc,
96-
}
97-
9899
#[turbo_tasks::value_impl]
99-
impl WithChunksChunkItemVc {
100-
#[turbo_tasks::function]
101-
async fn chunk_list_path(self) -> Result<FileSystemPathVc> {
102-
let this = self.await?;
103-
Ok(this.inner_context.chunk_list_path(this.inner.ident()))
104-
}
105-
100+
impl WithChunksAssetVc {
106101
#[turbo_tasks::function]
107102
async fn chunk_group(self) -> Result<ChunkGroupVc> {
108103
let this = self.await?;
109-
let inner = this.inner.await?;
110104
Ok(ChunkGroupVc::from_asset(
111-
inner.asset.into(),
112-
this.inner_context,
105+
this.asset.into(),
106+
this.chunking_context,
107+
Value::new(AvailabilityInfo::Root {
108+
current_availability_root: this.asset.into(),
109+
}),
113110
))
114111
}
115112
}
116113

114+
#[turbo_tasks::value]
115+
struct WithChunksChunkItem {
116+
context: ChunkingContextVc,
117+
inner: WithChunksAssetVc,
118+
}
119+
117120
#[turbo_tasks::value_impl]
118121
impl EcmascriptChunkItem for WithChunksChunkItem {
119122
#[turbo_tasks::function]
@@ -122,15 +125,14 @@ impl EcmascriptChunkItem for WithChunksChunkItem {
122125
}
123126

124127
#[turbo_tasks::function]
125-
async fn content(self_vc: WithChunksChunkItemVc) -> Result<EcmascriptChunkItemContentVc> {
126-
let this = self_vc.await?;
127-
let inner = this.inner.await?;
128-
let group = self_vc.chunk_group();
128+
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
129+
let inner = self.inner.await?;
130+
let group = self.inner.chunk_group();
129131
let chunks = group.chunks().await?;
130132
let server_root = inner.server_root.await?;
131133
let mut client_chunks = Vec::new();
132134

133-
let chunk_list_path = self_vc.chunk_list_path().await?;
135+
let chunk_list_path = group.chunk_list_path().await?;
134136
let chunk_list_path = if let Some(path) = server_root.get_path_to(&chunk_list_path) {
135137
path
136138
} else {
@@ -139,10 +141,16 @@ impl EcmascriptChunkItem for WithChunksChunkItem {
139141

140142
for chunk_path in chunks.iter().map(|c| c.path()).try_join().await? {
141143
if let Some(path) = server_root.get_path_to(&chunk_path) {
142-
client_chunks.push(Value::String(path.to_string()));
144+
client_chunks.push(serde_json::Value::String(path.to_string()));
143145
}
144146
}
145-
let module_id = stringify_js(&*inner.asset.as_chunk_item(this.inner_context).id().await?);
147+
let module_id = stringify_js(
148+
&*inner
149+
.asset
150+
.as_chunk_item(inner.chunking_context)
151+
.id()
152+
.await?,
153+
);
146154
Ok(EcmascriptChunkItemContent {
147155
inner_code: formatdoc! {
148156
r#"
@@ -171,58 +179,7 @@ impl ChunkItem for WithChunksChunkItem {
171179
}
172180

173181
#[turbo_tasks::function]
174-
async fn references(self_vc: WithChunksChunkItemVc) -> Result<AssetReferencesVc> {
175-
let this = self_vc.await?;
176-
let inner = this.inner.await?;
177-
Ok(AssetReferencesVc::cell(vec![
178-
WithChunksAssetReference {
179-
asset: InChunkingContextAsset {
180-
asset: inner.asset,
181-
chunking_context: this.inner_context,
182-
}
183-
.cell()
184-
.into(),
185-
}
186-
.cell()
187-
.into(),
188-
ChunkListReferenceVc::new(
189-
inner.server_root,
190-
self_vc.chunk_group(),
191-
self_vc.chunk_list_path(),
192-
)
193-
.into(),
194-
]))
195-
}
196-
}
197-
198-
#[turbo_tasks::value]
199-
struct WithChunksAssetReference {
200-
asset: AssetVc,
201-
}
202-
203-
#[turbo_tasks::value_impl]
204-
impl ValueToString for WithChunksAssetReference {
205-
#[turbo_tasks::function]
206-
async fn to_string(&self) -> Result<StringVc> {
207-
Ok(StringVc::cell(format!(
208-
"referenced asset {}",
209-
self.asset.ident().to_string().await?
210-
)))
211-
}
212-
}
213-
214-
#[turbo_tasks::value_impl]
215-
impl AssetReference for WithChunksAssetReference {
216-
#[turbo_tasks::function]
217-
fn resolve_reference(&self) -> ResolveResultVc {
218-
ResolveResult::asset(self.asset).cell()
219-
}
220-
}
221-
222-
#[turbo_tasks::value_impl]
223-
impl ChunkableAssetReference for WithChunksAssetReference {
224-
#[turbo_tasks::function]
225-
fn chunking_type(&self) -> ChunkingTypeOptionVc {
226-
ChunkingTypeOptionVc::cell(Some(ChunkingType::Separate))
182+
fn references(&self) -> AssetReferencesVc {
183+
self.inner.references()
227184
}
228185
}

crates/next-core/src/next_client_component/with_chunking_context_scope_asset.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use anyhow::Result;
2-
use turbo_tasks::primitives::StringVc;
2+
use turbo_tasks::{primitives::StringVc, Value};
33
use turbopack::ecmascript::chunk::{
44
EcmascriptChunkItemVc, EcmascriptChunkPlaceable, EcmascriptChunkPlaceableVc, EcmascriptChunkVc,
55
EcmascriptExportsVc,
66
};
77
use turbopack_core::{
88
asset::{Asset, AssetContentVc, AssetVc},
9-
chunk::{ChunkVc, ChunkableAsset, ChunkableAssetVc, ChunkingContext, ChunkingContextVc},
9+
chunk::{
10+
availability_info::AvailabilityInfo, ChunkVc, ChunkableAsset, ChunkableAssetVc,
11+
ChunkingContext, ChunkingContextVc,
12+
},
1013
ident::AssetIdentVc,
1114
reference::AssetReferencesVc,
1215
};
@@ -43,8 +46,17 @@ impl Asset for WithChunkingContextScopeAsset {
4346
#[turbo_tasks::value_impl]
4447
impl ChunkableAsset for WithChunkingContextScopeAsset {
4548
#[turbo_tasks::function]
46-
fn as_chunk(&self, context: ChunkingContextVc) -> ChunkVc {
47-
EcmascriptChunkVc::new(context.with_layer(&self.layer), self.asset).into()
49+
fn as_chunk(
50+
&self,
51+
context: ChunkingContextVc,
52+
availability_info: Value<AvailabilityInfo>,
53+
) -> ChunkVc {
54+
EcmascriptChunkVc::new(
55+
context.with_layer(&self.layer),
56+
self.asset,
57+
availability_info,
58+
)
59+
.into()
4860
}
4961
}
5062

0 commit comments

Comments
 (0)