Skip to content

Commit ff63646

Browse files
authored
[turbopack] Simplify JS ChunkItem with a single impl in most cases (#89548)
# What Removes the vast majority of `ChunkItem` implementations in favour of one `EcmascriptModuleChunkItem`. # Why Almost all of the `ChunkItem` implementations are trivial and were, for the most part, just places where additional traits could be implemented. By removing all of the various, trivial implementations, this might open up opportunities to better implement other features across the entire codebase. # How Most chunk items are migrated over to EcmascriptModuleChunkItem. The EcmascriptChunkPlaceable trait gains three new methods that modules can optionally override: - `chunk_item_content()` - generates the chunk item's JavaScript code - `chunk_item_content_ident()` - returns the content identity for cache invalidation - `chunk_item_output_assets()` - returns output assets the chunk item depends on The generic EcmascriptModuleChunkItem delegates to these trait methods, eliminating the need for per-module wrapper structs.
1 parent 9b0277f commit ff63646

File tree

42 files changed

+1278
-2048
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1278
-2048
lines changed

crates/next-core/src/hmr_entry.rs

Lines changed: 36 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,20 @@ use turbo_tasks_fs::{FileSystem, VirtualFileSystem, rope::RopeBuilder};
77
use turbopack_core::{
88
asset::{Asset, AssetContent},
99
chunk::{
10-
ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ChunkingType, ChunkingTypeOption,
11-
EvaluatableAsset,
10+
AsyncModuleInfo, ChunkItem, ChunkableModule, ChunkingContext, ChunkingType,
11+
ChunkingTypeOption, EvaluatableAsset,
1212
},
1313
ident::AssetIdent,
1414
module::{Module, ModuleSideEffects},
1515
module_graph::ModuleGraph,
16-
output::OutputAssetsReference,
1716
reference::{ModuleReference, ModuleReferences},
1817
resolve::ModuleResolveResult,
1918
source::OptionSource,
2019
};
2120
use turbopack_ecmascript::{
2221
chunk::{
23-
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions,
24-
EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports,
22+
EcmascriptChunkItemContent, EcmascriptChunkItemOptions, EcmascriptChunkPlaceable,
23+
EcmascriptExports, ecmascript_chunk_item,
2524
},
2625
runtime_functions::TURBOPACK_REQUIRE,
2726
utils::StringifyJs,
@@ -90,14 +89,7 @@ impl ChunkableModule for HmrEntryModule {
9089
module_graph: ResolvedVc<ModuleGraph>,
9190
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
9291
) -> Vc<Box<dyn ChunkItem>> {
93-
Vc::upcast(
94-
HmrEntryChunkItem {
95-
module: self,
96-
module_graph,
97-
chunking_context,
98-
}
99-
.cell(),
100-
)
92+
ecmascript_chunk_item(ResolvedVc::upcast(self), module_graph, chunking_context)
10193
}
10294
}
10395

@@ -115,6 +107,36 @@ impl EcmascriptChunkPlaceable for HmrEntryModule {
115107
fn get_exports(self: Vc<Self>) -> Vc<EcmascriptExports> {
116108
EcmascriptExports::None.cell()
117109
}
110+
111+
#[turbo_tasks::function]
112+
async fn chunk_item_content(
113+
self: Vc<Self>,
114+
chunking_context: Vc<Box<dyn ChunkingContext>>,
115+
module_graph: Vc<ModuleGraph>,
116+
_async_module_info: Option<Vc<AsyncModuleInfo>>,
117+
_estimated: bool,
118+
) -> Result<Vc<EcmascriptChunkItemContent>> {
119+
let this = self.await?;
120+
let module = this.module;
121+
let chunk_item = module.as_chunk_item(module_graph, chunking_context);
122+
let id = chunking_context
123+
.chunk_item_id_strategy()
124+
.await?
125+
.get_id(chunk_item)
126+
.await?;
127+
128+
let mut code = RopeBuilder::default();
129+
writeln!(code, "{TURBOPACK_REQUIRE}({});", StringifyJs(&id))?;
130+
Ok(EcmascriptChunkItemContent {
131+
inner_code: code.build(),
132+
options: EcmascriptChunkItemOptions {
133+
strict: true,
134+
..Default::default()
135+
},
136+
..Default::default()
137+
}
138+
.cell())
139+
}
118140
}
119141

120142
#[turbo_tasks::value_impl]
@@ -149,72 +171,10 @@ impl ModuleReference for HmrEntryModuleReference {
149171
}
150172

151173
#[turbo_tasks::function]
152-
fn chunking_type(self: Vc<Self>) -> Vc<ChunkingTypeOption> {
174+
fn chunking_type(&self) -> Vc<ChunkingTypeOption> {
153175
Vc::cell(Some(ChunkingType::Parallel {
154176
inherit_async: false,
155177
hoisted: false,
156178
}))
157179
}
158180
}
159-
160-
/// The chunk item for [`HmrEntryModule`].
161-
#[turbo_tasks::value]
162-
struct HmrEntryChunkItem {
163-
module: ResolvedVc<HmrEntryModule>,
164-
module_graph: ResolvedVc<ModuleGraph>,
165-
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
166-
}
167-
168-
#[turbo_tasks::value_impl]
169-
impl OutputAssetsReference for HmrEntryChunkItem {}
170-
171-
#[turbo_tasks::value_impl]
172-
impl ChunkItem for HmrEntryChunkItem {
173-
#[turbo_tasks::function]
174-
fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
175-
*self.chunking_context
176-
}
177-
178-
#[turbo_tasks::function]
179-
fn asset_ident(&self) -> Vc<AssetIdent> {
180-
self.module.ident()
181-
}
182-
183-
#[turbo_tasks::function]
184-
fn ty(&self) -> Vc<Box<dyn ChunkType>> {
185-
Vc::upcast(Vc::<EcmascriptChunkType>::default())
186-
}
187-
188-
#[turbo_tasks::function]
189-
fn module(&self) -> Vc<Box<dyn Module>> {
190-
Vc::upcast(*self.module)
191-
}
192-
}
193-
194-
#[turbo_tasks::value_impl]
195-
impl EcmascriptChunkItem for HmrEntryChunkItem {
196-
#[turbo_tasks::function]
197-
async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
198-
let this = self.module.await?;
199-
let module = this.module;
200-
let chunk_item = module.as_chunk_item(*self.module_graph, *self.chunking_context);
201-
let id = self
202-
.chunking_context
203-
.chunk_item_id_strategy()
204-
.await?
205-
.get_id(chunk_item)
206-
.await?;
207-
208-
let mut code = RopeBuilder::default();
209-
writeln!(code, "{TURBOPACK_REQUIRE}({});", StringifyJs(&id))?;
210-
Ok(EcmascriptChunkItemContent {
211-
inner_code: code.build(),
212-
options: EcmascriptChunkItemOptions {
213-
strict: true,
214-
..Default::default()
215-
},
216-
..Default::default()
217-
}
218-
.cell())
219-
}
220-
}

crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_module.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,17 @@ impl EcmascriptChunkPlaceable for EcmascriptClientReferenceModule {
281281
fn get_exports(self: Vc<Self>) -> Vc<EcmascriptExports> {
282282
self.proxy_module().get_exports()
283283
}
284+
285+
#[turbo_tasks::function]
286+
fn chunk_item_content(
287+
self: Vc<Self>,
288+
_chunking_context: Vc<Box<dyn ChunkingContext>>,
289+
_module_graph: Vc<ModuleGraph>,
290+
_async_module_info: Option<Vc<AsyncModuleInfo>>,
291+
_estimated: bool,
292+
) -> Result<Vc<EcmascriptChunkItemContent>> {
293+
bail!("Attempted to get chunk_item_content for EcmascriptClientReferenceModule")
294+
}
284295
}
285296

286297
/// This wrapper only exists to overwrite the `asset_ident` method of the

crates/next-core/src/next_dynamic/dynamic_module.rs

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,18 @@ use indoc::formatdoc;
55
use turbo_rcstr::{RcStr, rcstr};
66
use turbo_tasks::{ResolvedVc, Vc};
77
use turbopack_core::{
8-
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
8+
chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
99
ident::AssetIdent,
1010
module::{Module, ModuleSideEffects},
1111
module_graph::ModuleGraph,
12-
output::OutputAssetsReference,
1312
reference::{ModuleReferences, SingleChunkableModuleReference},
1413
resolve::ExportUsage,
1514
source::OptionSource,
1615
};
1716
use turbopack_ecmascript::{
1817
chunk::{
19-
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
20-
EcmascriptChunkType, EcmascriptExports,
18+
EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptExports,
19+
ecmascript_chunk_item,
2120
},
2221
references::esm::{EsmExport, EsmExports},
2322
runtime_functions::{TURBOPACK_EXPORT_NAMESPACE, TURBOPACK_IMPORT},
@@ -84,14 +83,7 @@ impl ChunkableModule for NextDynamicEntryModule {
8483
module_graph: ResolvedVc<ModuleGraph>,
8584
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
8685
) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
87-
Vc::upcast(
88-
NextDynamicEntryChunkItem {
89-
chunking_context,
90-
module_graph,
91-
inner: self,
92-
}
93-
.cell(),
94-
)
86+
ecmascript_chunk_item(ResolvedVc::upcast(self), module_graph, chunking_context)
9587
}
9688
}
9789

@@ -125,25 +117,16 @@ impl EcmascriptChunkPlaceable for NextDynamicEntryModule {
125117
)
126118
.cell())
127119
}
128-
}
129-
130-
#[turbo_tasks::value]
131-
struct NextDynamicEntryChunkItem {
132-
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
133-
module_graph: ResolvedVc<ModuleGraph>,
134-
inner: ResolvedVc<NextDynamicEntryModule>,
135-
}
136-
137-
#[turbo_tasks::value_impl]
138-
impl OutputAssetsReference for NextDynamicEntryChunkItem {}
139120

140-
#[turbo_tasks::value_impl]
141-
impl EcmascriptChunkItem for NextDynamicEntryChunkItem {
142121
#[turbo_tasks::function]
143-
async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
144-
let inner = self.inner.await?;
145-
146-
let module_id = inner.module.chunk_item_id(*self.chunking_context).await?;
122+
async fn chunk_item_content(
123+
&self,
124+
chunking_context: Vc<Box<dyn ChunkingContext>>,
125+
_module_graph: Vc<ModuleGraph>,
126+
_async_module_info: Option<Vc<AsyncModuleInfo>>,
127+
_estimated: bool,
128+
) -> Result<Vc<EcmascriptChunkItemContent>> {
129+
let module_id = self.module.chunk_item_id(chunking_context).await?;
147130
Ok(EcmascriptChunkItemContent {
148131
inner_code: formatdoc!(
149132
r#"
@@ -157,26 +140,3 @@ impl EcmascriptChunkItem for NextDynamicEntryChunkItem {
157140
.cell())
158141
}
159142
}
160-
161-
#[turbo_tasks::value_impl]
162-
impl ChunkItem for NextDynamicEntryChunkItem {
163-
#[turbo_tasks::function]
164-
fn asset_ident(&self) -> Vc<AssetIdent> {
165-
self.inner.ident()
166-
}
167-
168-
#[turbo_tasks::function]
169-
fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
170-
*self.chunking_context
171-
}
172-
173-
#[turbo_tasks::function]
174-
fn ty(&self) -> Vc<Box<dyn ChunkType>> {
175-
Vc::upcast(Vc::<EcmascriptChunkType>::default())
176-
}
177-
178-
#[turbo_tasks::function]
179-
fn module(&self) -> Vc<Box<dyn Module>> {
180-
Vc::upcast(*self.inner)
181-
}
182-
}

crates/next-core/src/next_server_component/server_component_module.rs

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@ use turbo_rcstr::rcstr;
66
use turbo_tasks::{ResolvedVc, Vc};
77
use turbo_tasks_fs::FileSystemPath;
88
use turbopack_core::{
9-
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
9+
chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
1010
ident::AssetIdent,
1111
module::{Module, ModuleSideEffects},
1212
module_graph::ModuleGraph,
13-
output::OutputAssetsReference,
1413
reference::ModuleReferences,
1514
source::OptionSource,
1615
};
1716
use turbopack_ecmascript::{
1817
chunk::{
19-
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
20-
EcmascriptChunkType, EcmascriptExports,
18+
EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptExports,
19+
ecmascript_chunk_item,
2120
},
2221
references::esm::{EsmExport, EsmExports},
2322
runtime_functions::{TURBOPACK_EXPORT_NAMESPACE, TURBOPACK_IMPORT},
@@ -101,14 +100,7 @@ impl ChunkableModule for NextServerComponentModule {
101100
module_graph: ResolvedVc<ModuleGraph>,
102101
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
103102
) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
104-
Vc::upcast(
105-
NextServerComponentChunkItem {
106-
module_graph,
107-
chunking_context,
108-
inner: self,
109-
}
110-
.cell(),
111-
)
103+
ecmascript_chunk_item(ResolvedVc::upcast(self), module_graph, chunking_context)
112104
}
113105
}
114106

@@ -138,25 +130,16 @@ impl EcmascriptChunkPlaceable for NextServerComponentModule {
138130
)
139131
.cell())
140132
}
141-
}
142-
143-
#[turbo_tasks::value]
144-
struct NextServerComponentChunkItem {
145-
module_graph: ResolvedVc<ModuleGraph>,
146-
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
147-
inner: ResolvedVc<NextServerComponentModule>,
148-
}
149-
150-
#[turbo_tasks::value_impl]
151-
impl OutputAssetsReference for NextServerComponentChunkItem {}
152133

153-
#[turbo_tasks::value_impl]
154-
impl EcmascriptChunkItem for NextServerComponentChunkItem {
155134
#[turbo_tasks::function]
156-
async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
157-
let inner = self.inner.await?;
158-
159-
let module_id = inner.module.chunk_item_id(*self.chunking_context).await?;
135+
async fn chunk_item_content(
136+
&self,
137+
chunking_context: Vc<Box<dyn ChunkingContext>>,
138+
_module_graph: Vc<ModuleGraph>,
139+
_async_module_info: Option<Vc<AsyncModuleInfo>>,
140+
_estimated: bool,
141+
) -> Result<Vc<EcmascriptChunkItemContent>> {
142+
let module_id = self.module.chunk_item_id(chunking_context).await?;
160143
Ok(EcmascriptChunkItemContent {
161144
inner_code: formatdoc!(
162145
r#"
@@ -170,26 +153,3 @@ impl EcmascriptChunkItem for NextServerComponentChunkItem {
170153
.cell())
171154
}
172155
}
173-
174-
#[turbo_tasks::value_impl]
175-
impl ChunkItem for NextServerComponentChunkItem {
176-
#[turbo_tasks::function]
177-
fn asset_ident(&self) -> Vc<AssetIdent> {
178-
self.inner.ident()
179-
}
180-
181-
#[turbo_tasks::function]
182-
fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
183-
*self.chunking_context
184-
}
185-
186-
#[turbo_tasks::function]
187-
fn ty(&self) -> Vc<Box<dyn ChunkType>> {
188-
Vc::upcast(Vc::<EcmascriptChunkType>::default())
189-
}
190-
191-
#[turbo_tasks::function]
192-
fn module(&self) -> Vc<Box<dyn Module>> {
193-
Vc::upcast(*self.inner)
194-
}
195-
}

0 commit comments

Comments
 (0)