Skip to content

Commit af27124

Browse files
committed
chunking_context.is_reference_unused
1 parent d79ea56 commit af27124

File tree

7 files changed

+110
-9
lines changed

7 files changed

+110
-9
lines changed

turbopack/crates/turbopack-browser/src/chunking_context.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ use turbopack_core::{
2525
ModuleGraph,
2626
chunk_group_info::ChunkGroup,
2727
export_usage::{ExportUsageInfo, ModuleExportUsage},
28+
import_usage::UnusedReferences,
2829
},
2930
output::{OutputAsset, OutputAssets},
31+
reference::ModuleReference,
3032
};
3133
use turbopack_ecmascript::{
3234
async_chunk::module::AsyncLoaderModule,
@@ -168,6 +170,14 @@ impl BrowserChunkingContextBuilder {
168170
self
169171
}
170172

173+
pub fn unused_references(
174+
mut self,
175+
unused_references: Option<ResolvedVc<UnusedReferences>>,
176+
) -> Self {
177+
self.chunking_context.unused_references = unused_references;
178+
self
179+
}
180+
171181
pub fn debug_ids(mut self, debug_ids: bool) -> Self {
172182
self.chunking_context.debug_ids = debug_ids;
173183
self
@@ -285,6 +295,8 @@ pub struct BrowserChunkingContext {
285295
module_id_strategy: ResolvedVc<Box<dyn ModuleIdStrategy>>,
286296
/// The module export usage info, if available.
287297
export_usage: Option<ResolvedVc<ExportUsageInfo>>,
298+
/// Which references are unused and should be skipped (e.g. during codegen).
299+
unused_references: Option<ResolvedVc<UnusedReferences>>,
288300
/// The chunking configs
289301
chunking_configs: Vec<(ResolvedVc<Box<dyn ChunkType>>, ChunkingConfig)>,
290302
/// Whether to use absolute URLs for static assets (e.g. in CSS: `url("/absolute/path")`)
@@ -332,6 +344,7 @@ impl BrowserChunkingContext {
332344
manifest_chunks: false,
333345
module_id_strategy: ResolvedVc::upcast(DevModuleIdStrategy::new_resolved()),
334346
export_usage: None,
347+
unused_references: None,
335348
chunking_configs: Default::default(),
336349
should_use_absolute_url_references: false,
337350
},
@@ -865,6 +878,20 @@ impl ChunkingContext for BrowserChunkingContext {
865878
}
866879
}
867880

881+
#[turbo_tasks::function]
882+
async fn is_reference_unused(
883+
self: Vc<Self>,
884+
reference: ResolvedVc<Box<dyn ModuleReference>>,
885+
) -> Result<Vc<bool>> {
886+
if let Some(unused_references) = self.await?.unused_references {
887+
Ok(Vc::cell(
888+
unused_references.await?.contains_reference(&reference),
889+
))
890+
} else {
891+
Ok(Vc::cell(false))
892+
}
893+
}
894+
868895
#[turbo_tasks::function]
869896
async fn debug_ids_enabled(self: Vc<Self>) -> Result<Vc<bool>> {
870897
Ok(Vc::cell(self.await?.debug_ids))

turbopack/crates/turbopack-core/src/chunk/chunking_context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{
1818
module_batches::BatchingConfig,
1919
},
2020
output::{OutputAsset, OutputAssets, OutputAssetsWithReferenced},
21+
reference::ModuleReference,
2122
};
2223

2324
#[derive(
@@ -317,6 +318,12 @@ pub trait ChunkingContext {
317318
module: Vc<Box<dyn Module>>,
318319
) -> Result<Vc<ModuleExportUsage>>;
319320

321+
#[turbo_tasks::function]
322+
async fn is_reference_unused(
323+
self: Vc<Self>,
324+
reference: Vc<Box<dyn ModuleReference>>,
325+
) -> Result<Vc<bool>>;
326+
320327
/// Returns whether debug IDs are enabled for this chunking context.
321328
#[turbo_tasks::function]
322329
fn debug_ids_enabled(self: Vc<Self>) -> Vc<bool>;

turbopack/crates/turbopack-core/src/reference/mod.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,15 @@ pub async fn primary_referenced_modules(module: Vc<Box<dyn Module>>) -> Result<V
286286
}
287287

288288
#[turbo_tasks::value(transparent)]
289-
pub struct ModulesWithRefData(Vec<(ChunkingType, ExportUsage, ImportUsage, ReadRef<Modules>)>);
289+
pub struct ModulesWithRefData(
290+
Vec<(
291+
ResolvedVc<Box<dyn ModuleReference>>,
292+
ChunkingType,
293+
ExportUsage,
294+
ImportUsage,
295+
ReadRef<Modules>,
296+
)>,
297+
);
290298

291299
/// Aggregates all primary [Module]s referenced by an [Module] via [ChunkableModuleReference]s.
292300
/// This does not include transitively referenced [Module]s, only includes
@@ -320,7 +328,13 @@ pub async fn primary_chunkable_referenced_modules(
320328
let export = reference.export_usage().owned().await?;
321329
let import = reference.import_usage().owned().await?;
322330

323-
return Ok(Some((chunking_type.clone(), export, import, resolved)));
331+
return Ok(Some((
332+
ResolvedVc::upcast(reference),
333+
chunking_type.clone(),
334+
export,
335+
import,
336+
resolved,
337+
)));
324338
}
325339
Ok(None)
326340
})

turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,13 @@ impl EsmAssetReference {
534534
) -> Result<CodeGeneration> {
535535
let this = &*self.await?;
536536

537+
if *chunking_context
538+
.is_reference_unused(Vc::upcast(self))
539+
.await?
540+
{
541+
return Ok(CodeGeneration::empty());
542+
}
543+
537544
// only chunked references can be imported
538545
if this.annotations.chunking_type() != Some("none") {
539546
let import_externals = this.import_externals;

turbopack/crates/turbopack-nodejs/src/chunking_context.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ use turbopack_core::{
2020
ModuleGraph,
2121
chunk_group_info::ChunkGroup,
2222
export_usage::{ExportUsageInfo, ModuleExportUsage},
23+
import_usage::UnusedReferences,
2324
},
2425
output::{OutputAsset, OutputAssets},
26+
reference::ModuleReference,
2527
};
2628
use turbopack_ecmascript::{
2729
async_chunk::module::AsyncLoaderModule,
@@ -117,6 +119,14 @@ impl NodeJsChunkingContextBuilder {
117119
self
118120
}
119121

122+
pub fn unused_references(
123+
mut self,
124+
unused_references: Option<ResolvedVc<UnusedReferences>>,
125+
) -> Self {
126+
self.chunking_context.unused_references = unused_references;
127+
self
128+
}
129+
120130
pub fn chunking_config<T>(mut self, ty: ResolvedVc<T>, chunking_config: ChunkingConfig) -> Self
121131
where
122132
T: Upcast<Box<dyn ChunkType>>,
@@ -182,6 +192,8 @@ pub struct NodeJsChunkingContext {
182192
module_id_strategy: ResolvedVc<Box<dyn ModuleIdStrategy>>,
183193
/// The module export usage info, if available.
184194
export_usage: Option<ResolvedVc<ExportUsageInfo>>,
195+
/// Which references are unused and should be skipped (e.g. during codegen).
196+
unused_references: Option<ResolvedVc<UnusedReferences>>,
185197
/// The strategy to use for generating source map source uris
186198
source_map_source_type: SourceMapSourceType,
187199
/// The chunking configs
@@ -225,6 +237,7 @@ impl NodeJsChunkingContext {
225237
source_map_source_type: SourceMapSourceType::TurbopackUri,
226238
module_id_strategy: ResolvedVc::upcast(DevModuleIdStrategy::new_resolved()),
227239
export_usage: None,
240+
unused_references: None,
228241
chunking_configs: Default::default(),
229242
debug_ids: false,
230243
},
@@ -600,6 +613,20 @@ impl ChunkingContext for NodeJsChunkingContext {
600613
}
601614
}
602615

616+
#[turbo_tasks::function]
617+
async fn is_reference_unused(
618+
self: Vc<Self>,
619+
reference: ResolvedVc<Box<dyn ModuleReference>>,
620+
) -> Result<Vc<bool>> {
621+
if let Some(unused_references) = self.await?.unused_references {
622+
Ok(Vc::cell(
623+
unused_references.await?.contains_reference(&reference),
624+
))
625+
} else {
626+
Ok(Vc::cell(false))
627+
}
628+
}
629+
603630
#[turbo_tasks::function]
604631
fn debug_ids_enabled(&self) -> Vc<bool> {
605632
Vc::cell(self.debug_ids)

turbopack/crates/turbopack-tests/tests/execution.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ use turbopack_core::{
3939
file_source::FileSource,
4040
ident::Layer,
4141
issue::CollectibleIssuesExt,
42-
module_graph::{ModuleGraph, export_usage::compute_export_usage_info},
42+
module_graph::{
43+
ModuleGraph, export_usage::compute_export_usage_info,
44+
import_usage::compute_import_usage_info,
45+
},
4346
reference_type::{InnerAssets, ReferenceType},
4447
resolve::{
4548
ExternalTraced, ExternalType,
@@ -474,9 +477,15 @@ async fn run_test_operation(prepared_test: ResolvedVc<PreparedTest>) -> Result<V
474477

475478
let mut module_graph = ModuleGraph::from_modules(entries.graph_entries(), false);
476479

477-
if options.remove_unused_imports {
478-
module_graph = module_graph.without_unused_references();
479-
}
480+
let unused_references = if options.remove_unused_imports {
481+
let unused_references = compute_import_usage_info(module_graph.to_resolved().await?)
482+
.resolve_strongly_consistent()
483+
.await?;
484+
module_graph = module_graph.without_unused_references(*unused_references);
485+
Some(unused_references)
486+
} else {
487+
None
488+
};
480489

481490
let chunking_context = NodeJsChunkingContext::builder(
482491
project_root.clone(),

turbopack/crates/turbopack-tests/tests/snapshot.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use turbopack_core::{
4949
ModuleGraph,
5050
chunk_group_info::{ChunkGroup, ChunkGroupEntry},
5151
export_usage::compute_export_usage_info,
52+
import_usage::compute_import_usage_info,
5253
},
5354
output::{OutputAsset, OutputAssets, OutputAssetsWithReferenced},
5455
reference_type::{EntryReferenceSubType, ReferenceType},
@@ -432,9 +433,16 @@ async fn run_test_operation(resource: RcStr) -> Result<Vc<FileSystemPath>> {
432433
Vc::cell(vec![ChunkGroupEntry::Entry(entry_modules.clone())]),
433434
false,
434435
);
435-
if options.remove_unused_imports {
436-
module_graph = module_graph.without_unused_references();
437-
}
436+
437+
let unused_references = if options.remove_unused_imports {
438+
let unused_references = compute_import_usage_info(module_graph.to_resolved().await?)
439+
.resolve_strongly_consistent()
440+
.await?;
441+
module_graph = module_graph.without_unused_references(*unused_references);
442+
Some(unused_references)
443+
} else {
444+
None
445+
};
438446

439447
let export_usage = if options.remove_unused_exports {
440448
Some(
@@ -469,6 +477,7 @@ async fn run_test_operation(resource: RcStr) -> Result<Vc<FileSystemPath>> {
469477
.minify_type(options.minify_type)
470478
.module_merging(options.scope_hoisting)
471479
.export_usage(export_usage)
480+
.unused_references(unused_references)
472481
.debug_ids(options.enable_debug_ids)
473482
.source_map_source_type(options.source_map_source_type);
474483

@@ -499,6 +508,7 @@ async fn run_test_operation(resource: RcStr) -> Result<Vc<FileSystemPath>> {
499508
.minify_type(options.minify_type)
500509
.module_merging(options.scope_hoisting)
501510
.export_usage(export_usage)
511+
.unused_references(unused_references)
502512
.debug_ids(options.enable_debug_ids)
503513
.source_map_source_type(options.source_map_source_type);
504514

0 commit comments

Comments
 (0)