From c69163d3689a7ec9b33bcc7bcb75c632a2130486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 14 Oct 2024 14:29:08 +0900 Subject: [PATCH 01/48] Prepare `select_part` --- .../src/references/esm/export.rs | 40 ++++- .../src/references/esm/mod.rs | 2 +- .../src/tree_shake/asset.rs | 144 ++++++++++++++++-- .../{.basic => basic}/input/index.js | 0 .../{.basic => basic}/options.json | 0 turbopack/crates/turbopack/src/lib.rs | 8 +- 6 files changed, 175 insertions(+), 19 deletions(-) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{.basic => basic}/input/index.js (100%) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{.basic => basic}/options.json (100%) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index e853a06886d4b..fba8d3c940d69 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -128,10 +128,12 @@ pub async fn follow_reexports( module: Vc>, export_name: RcStr, side_effect_free_packages: Vc, + ignore_side_effect_of_entry: Vc, ) -> Result> { - if !*module - .is_marked_as_side_effect_free(side_effect_free_packages) - .await? + if !*ignore_side_effect_of_entry.await? + && !*module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? { return Ok(FollowExportsResult::cell(FollowExportsResult { module, @@ -154,13 +156,20 @@ pub async fn follow_reexports( // Try to find the export in the local exports let exports_ref = exports.await?; if let Some(export) = exports_ref.exports.get(&export_name) { - match handle_declared_export(module, export_name, export, side_effect_free_packages) - .await? + match handle_declared_export( + module, + export_name.clone(), + export, + side_effect_free_packages, + ) + .await? { ControlFlow::Continue((m, n)) => { - module = m; - export_name = n; - continue; + if !is_module_part_with_no_real_export(m).await? { + module = m; + export_name = n; + continue; + } } ControlFlow::Break(result) => { return Ok(result.cell()); @@ -205,6 +214,21 @@ pub async fn follow_reexports( } } +async fn is_module_part_with_no_real_export( + module: Vc>, +) -> Result { + if let Some(module) = Vc::try_resolve_downcast_type::(module).await? + { + if matches!( + *module.await?.part.await?, + ModulePart::Internal(..) | ModulePart::Evaluation + ) { + return Ok(true); + } + } + Ok(false) +} + async fn handle_declared_export( module: Vc>, export_name: RcStr, diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs index 1e44b3656b61f..f9b41f846adfc 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs @@ -11,7 +11,7 @@ pub use self::{ base::EsmAssetReference, binding::EsmBinding, dynamic::EsmAsyncAssetReference, - export::{EsmExport, EsmExports}, + export::{EsmExport, EsmExports, FoundExportType}, meta::{ImportMetaBinding, ImportMetaRef}, module_item::EsmModuleItem, url::{UrlAssetReference, UrlRewriteBehavior}, diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 6c37c96622bec..508bd208beeb3 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,12 +1,15 @@ use anyhow::{Context, Result}; -use turbo_tasks::{ResolvedVc, Vc}; +use turbo_rcstr::RcStr; +use turbo_tasks::{vdbg, ResolvedVc, ValueToString, Vc}; +use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, EvaluatableAsset}, + context::AssetContext, ident::AssetIdent, module::Module, reference::{ModuleReference, ModuleReferences, SingleModuleReference}, - resolve::ModulePart, + resolve::{origin::ResolveOrigin, ModulePart}, }; use super::{ @@ -16,7 +19,10 @@ use super::{ use crate::{ chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, parse::ParseResult, - references::analyse_ecmascript_module, + references::{ + analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, + }, + tree_shake::Key, AnalyzeEcmascriptModuleResult, EcmascriptAnalyzable, EcmascriptModuleAsset, EcmascriptModuleAssetType, EcmascriptModuleContent, EcmascriptParsable, }; @@ -95,13 +101,66 @@ impl EcmascriptModulePartAsset { module: Vc, part: Vc, ) -> Result>> { - let split_result = split_module(module).await?; + let SplitResult::Ok { entrypoints, .. } = &*split_module(module).await? else { + return Ok(Vc::upcast(module)); + }; - Ok(if matches!(&*split_result, SplitResult::Failed { .. }) { - Vc::upcast(module) - } else { - Vc::upcast(EcmascriptModulePartAsset::new(module, part)) - }) + // We follow reexports here + if let ModulePart::Export(export) = &*part.await? { + let export_name = export.await?.clone_value(); + + // If a local binding or reexport with the same name exists, we stop here. + // Side effects of the barrel file are preserved. + if entrypoints.contains_key(&Key::Export(export_name.clone())) { + return Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, part))); + } + + let side_effect_free_packages = module.asset_context().side_effect_free_packages(); + + // Exclude local bindings by using exports module part. + let source_module = if entrypoints.contains_key(&Key::Exports) + && *module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + Vc::upcast(EcmascriptModulePartAsset::new( + module, + ModulePart::exports(), + )) + } else { + Vc::upcast(module) + }; + + let FollowExportsWithSideEffectsResult { + side_effects, + result, + } = &*follow_reexports_with_side_effects( + source_module, + export_name.clone(), + side_effect_free_packages, + ) + .await?; + + let FollowExportsResult { + module: final_module, + export_name: new_export, + ty, + } = &*result.await?; + + vdbg!( + *ty, + final_module.ident().to_string().await?, + new_export.clone() + ); + + if let Some(new_export) = new_export { + if *new_export == export_name { + return Ok(Vc::upcast(*final_module)); + } + } + } + + Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, part))) } #[turbo_tasks::function] @@ -117,6 +176,58 @@ impl EcmascriptModulePartAsset { } } +#[turbo_tasks::value] +struct FollowExportsWithSideEffectsResult { + side_effects: Vc, + result: Vc, +} + +#[turbo_tasks::value(transparent)] +struct SideEffects(Vec>>); + +#[turbo_tasks::function] +async fn follow_reexports_with_side_effects( + module: Vc>, + export_name: RcStr, + side_effect_free_packages: Vc, +) -> Result> { + let mut side_effects = vec![]; + + let mut current_module = module; + let mut current_export_name = export_name; + let result = loop { + // We ignore the side effect of the entry module here, because we need to proceed. + let result = follow_reexports( + current_module, + current_export_name.clone(), + side_effect_free_packages, + Vc::cell(true), + ); + dbg!(&*current_module.ident().to_string().await?); + + let FollowExportsResult { + module, + export_name, + ty, + } = &*result.await?; + + match ty { + FoundExportType::SideEffects => { + side_effects.push(*module); + current_module = *module; + current_export_name = export_name.clone().unwrap_or(current_export_name); + } + _ => break result, + } + }; + + Ok(FollowExportsWithSideEffectsResult { + side_effects: Vc::cell(side_effects), + result, + } + .cell()) +} + #[turbo_tasks::value_impl] impl Module for EcmascriptModulePartAsset { #[turbo_tasks::function] @@ -199,6 +310,21 @@ impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { async fn get_exports(self: Vc) -> Result> { Ok(*self.analyze().await?.exports) } + + #[turbo_tasks::function] + async fn is_marked_as_side_effect_free( + self: Vc, + side_effect_free_packages: Vc, + ) -> Result> { + let this = self.await?; + + match *this.part.await? { + ModulePart::Exports | ModulePart::Export(..) => Ok(Vc::cell(true)), + _ => Ok(this + .full_module + .is_marked_as_side_effect_free(side_effect_free_packages)), + } + } } #[turbo_tasks::value_impl] diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs index 60e2b3f85c6cc..5b56db8e641dc 100644 --- a/turbopack/crates/turbopack/src/lib.rs +++ b/turbopack/crates/turbopack/src/lib.rs @@ -287,7 +287,13 @@ async fn apply_reexport_tree_shaking( module: final_module, export_name: new_export, .. - } = &*follow_reexports(module, export.clone_value(), side_effect_free_packages).await?; + } = &*follow_reexports( + module, + export.clone_value(), + side_effect_free_packages, + Vc::cell(false), + ) + .await?; let module = if let Some(new_export) = new_export { if *new_export == *export { Vc::upcast(*final_module) From 325bac6aab7ead515f5916469c9592d9473328df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 09:56:50 +0900 Subject: [PATCH 02/48] Remove dbg import --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 508bd208beeb3..1d41aa4a3beed 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -144,15 +144,9 @@ impl EcmascriptModulePartAsset { let FollowExportsResult { module: final_module, export_name: new_export, - ty, + .. } = &*result.await?; - vdbg!( - *ty, - final_module.ident().to_string().await?, - new_export.clone() - ); - if let Some(new_export) = new_export { if *new_export == export_name { return Ok(Vc::upcast(*final_module)); @@ -203,7 +197,6 @@ async fn follow_reexports_with_side_effects( side_effect_free_packages, Vc::cell(true), ); - dbg!(&*current_module.ident().to_string().await?); let FollowExportsResult { module, From cd9eb516fcb0e2552484d923436c08779cf3862b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 15 Oct 2024 09:57:33 +0900 Subject: [PATCH 03/48] Update turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs Co-authored-by: Tobias Koppers fixup fixup --- .../crates/turbopack-ecmascript/src/references/esm/export.rs | 4 ++-- turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs | 2 +- turbopack/crates/turbopack/src/lib.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index fba8d3c940d69..e9ee0e10b3d2a 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -128,9 +128,9 @@ pub async fn follow_reexports( module: Vc>, export_name: RcStr, side_effect_free_packages: Vc, - ignore_side_effect_of_entry: Vc, + ignore_side_effect_of_entry: bool, ) -> Result> { - if !*ignore_side_effect_of_entry.await? + if !ignore_side_effect_of_entry && !*module .is_marked_as_side_effect_free(side_effect_free_packages) .await? diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 1d41aa4a3beed..91098f7eb78fa 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -195,7 +195,7 @@ async fn follow_reexports_with_side_effects( current_module, current_export_name.clone(), side_effect_free_packages, - Vc::cell(true), + true, ); let FollowExportsResult { diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs index 5b56db8e641dc..218ee19c510b6 100644 --- a/turbopack/crates/turbopack/src/lib.rs +++ b/turbopack/crates/turbopack/src/lib.rs @@ -291,7 +291,7 @@ async fn apply_reexport_tree_shaking( module, export.clone_value(), side_effect_free_packages, - Vc::cell(false), + false, ) .await?; let module = if let Some(new_export) = new_export { From 5efec0581e0455162bd06ef01f4b7076f521a940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 10:18:58 +0900 Subject: [PATCH 04/48] Preserve side effects using `SideEffectsModule` --- .../src/tree_shake/asset.rs | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 91098f7eb78fa..51af51c6c45d7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -149,7 +149,15 @@ impl EcmascriptModulePartAsset { if let Some(new_export) = new_export { if *new_export == export_name { - return Ok(Vc::upcast(*final_module)); + let side_effects = side_effects.await?.to_vec(); + + return Ok(Vc::upcast( + SideEffectsModule { + module: *final_module, + side_effects: Vc::cell(side_effects), + } + .cell(), + )); } } } @@ -170,6 +178,49 @@ impl EcmascriptModulePartAsset { } } +#[turbo_tasks::value] +struct SideEffectsModule { + module: Vc>, + side_effects: Vc, +} + +#[turbo_tasks::value_impl] +impl Asset for SideEffectsModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + unreachable!("SideEffectsModule has no content") + } +} + +#[turbo_tasks::value_impl] +impl Module for SideEffectsModule { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.module + .ident() + .with_modifier(Vc::cell(RcStr::from("with intermediate side-effects"))) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let mut references = vec![]; + + for &side_effect in self.side_effects.await?.iter() { + references.push(Vc::upcast(SingleModuleReference::new( + Vc::upcast(side_effect), + Vc::cell(RcStr::from("side effect")), + ))); + } + + references.push(Vc::upcast(SingleModuleReference::new( + Vc::upcast(self.module), + Vc::cell(RcStr::from("target binding")), + ))); + + Ok(Vc::cell(references)) + } +} + #[turbo_tasks::value] struct FollowExportsWithSideEffectsResult { side_effects: Vc, From dde4d510996e987855febab552fbfdea46ddc486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 10:45:01 +0900 Subject: [PATCH 05/48] [TMP] Add logging for side effect nodes --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 51af51c6c45d7..b2c5f56599620 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -151,6 +151,11 @@ impl EcmascriptModulePartAsset { if *new_export == export_name { let side_effects = side_effects.await?.to_vec(); + vdbg!("side effects"); + for side_effect in side_effects.iter() { + vdbg!(side_effect.ident().to_string().await?); + } + return Ok(Vc::upcast( SideEffectsModule { module: *final_module, @@ -206,12 +211,15 @@ impl Module for SideEffectsModule { let mut references = vec![]; for &side_effect in self.side_effects.await?.iter() { + vdbg!(side_effect.ident().to_string().await?); references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), ))); } + vdbg!(self.module.ident().to_string().await?); + references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(self.module), Vc::cell(RcStr::from("target binding")), @@ -255,6 +263,8 @@ async fn follow_reexports_with_side_effects( ty, } = &*result.await?; + dbg!("ty", ty); + match ty { FoundExportType::SideEffects => { side_effects.push(*module); From a7bf6df5e407ffa579c668150ae9959a654c77e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 10:53:52 +0900 Subject: [PATCH 06/48] Fix `follow_reexports` for original case --- .../crates/turbopack-ecmascript/src/references/esm/export.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index e9ee0e10b3d2a..b41e699e28591 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -165,7 +165,9 @@ pub async fn follow_reexports( .await? { ControlFlow::Continue((m, n)) => { - if !is_module_part_with_no_real_export(m).await? { + if !ignore_side_effect_of_entry + || !is_module_part_with_no_real_export(m).await? + { module = m; export_name = n; continue; From 38c399e0e5de2f1b33d9d859b66d949dc5fec2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 10:58:19 +0900 Subject: [PATCH 07/48] Revert chganges in `follow_reexports` --- .../src/references/esm/export.rs | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index b41e699e28591..8ea7e0fd87f94 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -165,13 +165,9 @@ pub async fn follow_reexports( .await? { ControlFlow::Continue((m, n)) => { - if !ignore_side_effect_of_entry - || !is_module_part_with_no_real_export(m).await? - { - module = m; - export_name = n; - continue; - } + module = m; + export_name = n; + continue; } ControlFlow::Break(result) => { return Ok(result.cell()); @@ -216,21 +212,6 @@ pub async fn follow_reexports( } } -async fn is_module_part_with_no_real_export( - module: Vc>, -) -> Result { - if let Some(module) = Vc::try_resolve_downcast_type::(module).await? - { - if matches!( - *module.await?.part.await?, - ModulePart::Internal(..) | ModulePart::Evaluation - ) { - return Ok(true); - } - } - Ok(false) -} - async fn handle_declared_export( module: Vc>, export_name: RcStr, From b3a2ab7bf32eab694f3dc53620af68b0b9bd328f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 11:16:39 +0900 Subject: [PATCH 08/48] Fix resolving issues --- .../src/tree_shake/asset.rs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index b2c5f56599620..25ef248bc0eb7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -22,6 +22,7 @@ use crate::{ references::{ analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, }, + side_effect_optimization::facade::module::EcmascriptModuleFacadeModule, tree_shake::Key, AnalyzeEcmascriptModuleResult, EcmascriptAnalyzable, EcmascriptModuleAsset, EcmascriptModuleAssetType, EcmascriptModuleContent, EcmascriptParsable, @@ -147,24 +148,31 @@ impl EcmascriptModulePartAsset { .. } = &*result.await?; - if let Some(new_export) = new_export { + let final_module = if let Some(new_export) = new_export { if *new_export == export_name { - let side_effects = side_effects.await?.to_vec(); + *final_module + } else { + Vc::upcast(EcmascriptModuleFacadeModule::new( + *final_module, + ModulePart::renamed_export(new_export.clone(), export_name.clone()), + )) + } + } else { + Vc::upcast(EcmascriptModuleFacadeModule::new( + *final_module, + ModulePart::renamed_namespace(export_name.clone()), + )) + }; - vdbg!("side effects"); - for side_effect in side_effects.iter() { - vdbg!(side_effect.ident().to_string().await?); - } + let side_effects = side_effects.await?.to_vec(); - return Ok(Vc::upcast( - SideEffectsModule { - module: *final_module, - side_effects: Vc::cell(side_effects), - } - .cell(), - )); + return Ok(Vc::upcast( + SideEffectsModule { + module: final_module, + side_effects: Vc::cell(side_effects), } - } + .cell(), + )); } Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, part))) From 0bd6263c4ca3f6faf97cc2d67a7dc2b78e504329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 11:25:20 +0900 Subject: [PATCH 09/48] Fix `follow_reexports_with_side_effects` --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 25ef248bc0eb7..5761386458290 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -219,15 +219,12 @@ impl Module for SideEffectsModule { let mut references = vec![]; for &side_effect in self.side_effects.await?.iter() { - vdbg!(side_effect.ident().to_string().await?); references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), ))); } - vdbg!(self.module.ident().to_string().await?); - references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(self.module), Vc::cell(RcStr::from("target binding")), @@ -257,6 +254,13 @@ async fn follow_reexports_with_side_effects( let mut current_module = module; let mut current_export_name = export_name; let result = loop { + if !*current_module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + side_effects.push(current_module); + } + // We ignore the side effect of the entry module here, because we need to proceed. let result = follow_reexports( current_module, @@ -271,8 +275,6 @@ async fn follow_reexports_with_side_effects( ty, } = &*result.await?; - dbg!("ty", ty); - match ty { FoundExportType::SideEffects => { side_effects.push(*module); From bdf93bfcdd4ea696d7e2efeb02671cd7e397d7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 11:48:43 +0900 Subject: [PATCH 10/48] impl EcmascriptChunkPlaceable for SideEffectsModule --- .../src/tree_shake/asset.rs | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 5761386458290..9db6d2d6d03ab 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -197,14 +197,6 @@ struct SideEffectsModule { side_effects: Vc, } -#[turbo_tasks::value_impl] -impl Asset for SideEffectsModule { - #[turbo_tasks::function] - fn content(&self) -> Vc { - unreachable!("SideEffectsModule has no content") - } -} - #[turbo_tasks::value_impl] impl Module for SideEffectsModule { #[turbo_tasks::function] @@ -218,7 +210,9 @@ impl Module for SideEffectsModule { async fn references(&self) -> Result> { let mut references = vec![]; + dbg!(self.module.ident().to_string().await?); for &side_effect in self.side_effects.await?.iter() { + dbg!(side_effect.ident().to_string().await?); references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), @@ -234,6 +228,46 @@ impl Module for SideEffectsModule { } } +#[turbo_tasks::value_impl] +impl Asset for SideEffectsModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + unreachable!("SideEffectsModule has no content") + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for SideEffectsModule { + #[turbo_tasks::function] + async fn get_exports(&self) -> Vc { + self.module.get_exports() + } + + #[turbo_tasks::function] + async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { + Vc::cell(false) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for SideEffectsModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok( + Vc::try_resolve_sidecast::>(self.await?.module) + .await? + .unwrap() + .as_chunk_item(chunking_context), + ) + } +} + +#[turbo_tasks::value_impl] +impl EvaluatableAsset for SideEffectsModule {} + #[turbo_tasks::value] struct FollowExportsWithSideEffectsResult { side_effects: Vc, From d85c2a3d23a3ee903cbd6682ffb141580d8d82f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 13:50:33 +0900 Subject: [PATCH 11/48] Declare a chunk item for `SideEffectsModule` --- .../src/tree_shake/asset.rs | 79 ++++++++++++++++--- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 9db6d2d6d03ab..0af3a232d9fe1 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,10 +1,12 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{vdbg, ResolvedVc, ValueToString, Vc}; +use turbo_tasks::{vdbg, ResolvedVc, ValueDefault, ValueToString, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, EvaluatableAsset}, + chunk::{ + AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, + }, context::AssetContext, ident::AssetIdent, module::Module, @@ -17,7 +19,10 @@ use super::{ PartId, SplitResult, }; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, parse::ParseResult, references::{ analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, @@ -249,6 +254,52 @@ impl EcmascriptChunkPlaceable for SideEffectsModule { } } +#[turbo_tasks::value] +struct SideEffectsModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for SideEffectsModuleChunkItem { + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn ty(&self) -> Vc> { + Vc::upcast(EcmascriptChunkType::value_default()) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for SideEffectsModuleChunkItem { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should never be called"); + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} + #[turbo_tasks::value_impl] impl ChunkableModule for SideEffectsModule { #[turbo_tasks::function] @@ -256,12 +307,13 @@ impl ChunkableModule for SideEffectsModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - Ok( - Vc::try_resolve_sidecast::>(self.await?.module) - .await? - .unwrap() - .as_chunk_item(chunking_context), - ) + Ok(Vc::upcast( + SideEffectsModuleChunkItem { + module: self, + chunking_context, + } + .cell(), + )) } } @@ -288,12 +340,13 @@ async fn follow_reexports_with_side_effects( let mut current_module = module; let mut current_export_name = export_name; let result = loop { - if !*current_module + let ignore = !*current_module .is_marked_as_side_effect_free(side_effect_free_packages) - .await? - { + .await?; + if ignore { side_effects.push(current_module); } + vdbg!(ignore, current_module.ident().to_string().await?); // We ignore the side effect of the entry module here, because we need to proceed. let result = follow_reexports( @@ -309,6 +362,8 @@ async fn follow_reexports_with_side_effects( ty, } = &*result.await?; + vdbg!(ty, module.ident().to_string().await?); + match ty { FoundExportType::SideEffects => { side_effects.push(*module); From ef227df7901a81c930c8e9846480ab2b000d082d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 14:12:57 +0900 Subject: [PATCH 12/48] Chunk item --- .../src/tree_shake/asset.rs | 68 +++---------------- .../src/tree_shake/chunk_item.rs | 58 +++++++++++++++- 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 0af3a232d9fe1..cc91846092312 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,12 +1,10 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{vdbg, ResolvedVc, ValueDefault, ValueToString, Vc}; +use turbo_tasks::{vdbg, ResolvedVc, ValueToString, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{ - AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, - }, + chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, EvaluatableAsset}, context::AssetContext, ident::AssetIdent, module::Module, @@ -19,16 +17,13 @@ use super::{ PartId, SplitResult, }; use crate::{ - chunk::{ - EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptExports, - }, + chunk::{EcmascriptChunkItem, EcmascriptChunkPlaceable, EcmascriptExports}, parse::ParseResult, references::{ analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, }, side_effect_optimization::facade::module::EcmascriptModuleFacadeModule, - tree_shake::Key, + tree_shake::{chunk_item::SideEffectsModuleChunkItem, Key}, AnalyzeEcmascriptModuleResult, EcmascriptAnalyzable, EcmascriptModuleAsset, EcmascriptModuleAssetType, EcmascriptModuleContent, EcmascriptParsable, }; @@ -197,7 +192,7 @@ impl EcmascriptModulePartAsset { } #[turbo_tasks::value] -struct SideEffectsModule { +pub(super) struct SideEffectsModule { module: Vc>, side_effects: Vc, } @@ -254,52 +249,6 @@ impl EcmascriptChunkPlaceable for SideEffectsModule { } } -#[turbo_tasks::value] -struct SideEffectsModuleChunkItem { - module: Vc, - chunking_context: Vc>, -} - -#[turbo_tasks::value_impl] -impl ChunkItem for SideEffectsModuleChunkItem { - #[turbo_tasks::function] - fn references(&self) -> Vc { - self.module.references() - } - - #[turbo_tasks::function] - fn asset_ident(&self) -> Vc { - self.module.ident() - } - - #[turbo_tasks::function] - fn ty(&self) -> Vc> { - Vc::upcast(EcmascriptChunkType::value_default()) - } - - #[turbo_tasks::function] - fn module(&self) -> Vc> { - Vc::upcast(self.module) - } - - #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { - self.chunking_context - } -} -#[turbo_tasks::value_impl] -impl EcmascriptChunkItem for SideEffectsModuleChunkItem { - #[turbo_tasks::function] - fn content(self: Vc) -> Vc { - panic!("content() should never be called"); - } - - #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { - self.chunking_context - } -} - #[turbo_tasks::value_impl] impl ChunkableModule for SideEffectsModule { #[turbo_tasks::function] @@ -307,10 +256,15 @@ impl ChunkableModule for SideEffectsModule { self: Vc, chunking_context: Vc>, ) -> Result>> { + let chunk_item = self.await?.module.as_chunk_item(chunking_context); + let chunk_item = Vc::try_resolve_sidecast::>(chunk_item) + .await? + .unwrap(); + Ok(Vc::upcast( SideEffectsModuleChunkItem { module: self, - chunking_context, + chunk_item, } .cell(), )) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 28d1428927656..3db2e6e3b6907 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{ResolvedVc, Vc}; +use turbo_tasks::{ResolvedVc, ValueDefault, Vc}; use turbopack_core::{ chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkingContext}, ident::AssetIdent, @@ -10,6 +10,7 @@ use turbopack_core::{ use super::{asset::EcmascriptModulePartAsset, part_of_module, split_module}; use crate::{ chunk::{EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType}, + tree_shake::asset::SideEffectsModule, EcmascriptModuleContent, }; @@ -106,3 +107,58 @@ impl ChunkItem for EcmascriptModulePartChunkItem { self.module.is_async_module() } } + +#[turbo_tasks::value(shared)] +pub(super) struct SideEffectsModuleChunkItem { + pub module: Vc, + pub chunk_item: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for SideEffectsModuleChunkItem { + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.chunk_item.references() + } + + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn ty(&self) -> Vc> { + Vc::upcast(EcmascriptChunkType::value_default()) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + EcmascriptChunkItem::chunking_context(self.chunk_item) + } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for SideEffectsModuleChunkItem { + #[turbo_tasks::function] + fn content(&self) -> Vc { + EcmascriptChunkItem::content(self.chunk_item) + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Vc { + self.chunk_item + .content_with_async_module_info(async_module_info) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + EcmascriptChunkItem::chunking_context(self.chunk_item) + } +} From f9b1d6eb15c7f0de7c3f8ac51d5542773efa556b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 14:39:40 +0900 Subject: [PATCH 13/48] We need to implement it manually --- .../src/tree_shake/asset.rs | 11 ++------ .../src/tree_shake/chunk_item.rs | 28 +++++-------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index cc91846092312..f489ade508a42 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -17,7 +17,7 @@ use super::{ PartId, SplitResult, }; use crate::{ - chunk::{EcmascriptChunkItem, EcmascriptChunkPlaceable, EcmascriptExports}, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, parse::ParseResult, references::{ analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, @@ -210,9 +210,7 @@ impl Module for SideEffectsModule { async fn references(&self) -> Result> { let mut references = vec![]; - dbg!(self.module.ident().to_string().await?); for &side_effect in self.side_effects.await?.iter() { - dbg!(side_effect.ident().to_string().await?); references.push(Vc::upcast(SingleModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), @@ -256,15 +254,10 @@ impl ChunkableModule for SideEffectsModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunk_item = self.await?.module.as_chunk_item(chunking_context); - let chunk_item = Vc::try_resolve_sidecast::>(chunk_item) - .await? - .unwrap(); - Ok(Vc::upcast( SideEffectsModuleChunkItem { module: self, - chunk_item, + chunking_context, } .cell(), )) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 3db2e6e3b6907..9e87a996407a4 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -111,20 +111,16 @@ impl ChunkItem for EcmascriptModulePartChunkItem { #[turbo_tasks::value(shared)] pub(super) struct SideEffectsModuleChunkItem { pub module: Vc, - pub chunk_item: Vc>, + pub chunking_context: Vc>, } #[turbo_tasks::value_impl] impl ChunkItem for SideEffectsModuleChunkItem { #[turbo_tasks::function] - fn references(&self) -> Vc { - self.chunk_item.references() - } + fn references(&self) -> Vc {} #[turbo_tasks::function] - fn asset_ident(&self) -> Vc { - self.module.ident() - } + fn asset_ident(&self) -> Vc {} #[turbo_tasks::function] fn ty(&self) -> Vc> { @@ -132,33 +128,23 @@ impl ChunkItem for SideEffectsModuleChunkItem { } #[turbo_tasks::function] - fn module(&self) -> Vc> { - Vc::upcast(self.module) - } + fn module(&self) -> Vc> {} #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { - EcmascriptChunkItem::chunking_context(self.chunk_item) - } + fn chunking_context(&self) -> Vc> {} } #[turbo_tasks::value_impl] impl EcmascriptChunkItem for SideEffectsModuleChunkItem { #[turbo_tasks::function] - fn content(&self) -> Vc { - EcmascriptChunkItem::content(self.chunk_item) - } + fn content(&self) -> Vc {} #[turbo_tasks::function] async fn content_with_async_module_info( &self, async_module_info: Option>, ) -> Vc { - self.chunk_item - .content_with_async_module_info(async_module_info) } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { - EcmascriptChunkItem::chunking_context(self.chunk_item) - } + fn chunking_context(&self) -> Vc> {} } From 485c196634f7a0fc4f9343195e27d76dffbaa8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 14:59:41 +0900 Subject: [PATCH 14/48] trivial impls WIP: codegen has_top_level_await __turbopack_import__ `__turbopack_export_namespace__(__turbopack_import__({}))` --- .../src/references/esm/export.rs | 2 + .../src/tree_shake/asset.rs | 6 +- .../src/tree_shake/chunk_item.rs | 90 ++++++++++++++++--- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 8ea7e0fd87f94..1f667142d4c35 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -25,6 +25,7 @@ use turbopack_core::{ issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, StyledString}, module::Module, reference::ModuleReference, + resolve::ModulePart, }; use super::base::ReferencedAsset; @@ -32,6 +33,7 @@ use crate::{ chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGenerateable, CodeGeneration, CodeGenerationHoistedStmt}, magic_identifier, + tree_shake::asset::EcmascriptModulePartAsset, }; #[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index f489ade508a42..6cd4f76c3b300 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -193,8 +193,8 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] pub(super) struct SideEffectsModule { - module: Vc>, - side_effects: Vc, + pub module: Vc>, + pub side_effects: Vc, } #[turbo_tasks::value_impl] @@ -274,7 +274,7 @@ struct FollowExportsWithSideEffectsResult { } #[turbo_tasks::value(transparent)] -struct SideEffects(Vec>>); +pub(super) struct SideEffects(pub Vec>>); #[turbo_tasks::function] async fn follow_reexports_with_side_effects( diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 9e87a996407a4..4848fcec597e0 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -1,5 +1,6 @@ use anyhow::Result; -use turbo_tasks::{ResolvedVc, ValueDefault, Vc}; +use turbo_tasks::{ResolvedVc, ValueDefault, ValueToString, Vc}; +use turbo_tasks_fs::rope::RopeBuilder; use turbopack_core::{ chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkingContext}, ident::AssetIdent, @@ -9,8 +10,13 @@ use turbopack_core::{ use super::{asset::EcmascriptModulePartAsset, part_of_module, split_module}; use crate::{ - chunk::{EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType}, + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions, + EcmascriptChunkPlaceable, EcmascriptChunkType, + }, + references::async_module::AsyncModuleOptions, tree_shake::asset::SideEffectsModule, + utils::StringifyJs, EcmascriptModuleContent, }; @@ -117,10 +123,14 @@ pub(super) struct SideEffectsModuleChunkItem { #[turbo_tasks::value_impl] impl ChunkItem for SideEffectsModuleChunkItem { #[turbo_tasks::function] - fn references(&self) -> Vc {} + fn references(&self) -> Vc { + self.module.references() + } #[turbo_tasks::function] - fn asset_ident(&self) -> Vc {} + fn asset_ident(&self) -> Vc { + self.module.ident() + } #[turbo_tasks::function] fn ty(&self) -> Vc> { @@ -128,23 +138,77 @@ impl ChunkItem for SideEffectsModuleChunkItem { } #[turbo_tasks::function] - fn module(&self) -> Vc> {} + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> {} + fn chunking_context(&self) -> Vc> { + self.chunking_context + } } + #[turbo_tasks::value_impl] impl EcmascriptChunkItem for SideEffectsModuleChunkItem { #[turbo_tasks::function] - fn content(&self) -> Vc {} + async fn content(&self) -> Result> { + let mut code = RopeBuilder::default(); + let mut has_top_level_await = false; - #[turbo_tasks::function] - async fn content_with_async_module_info( - &self, - async_module_info: Option>, - ) -> Vc { + let module = self.module.await?; + + code.push_bytes( + format!( + "__turbopack_export_namespace__(__turbopack_import__({}));\n", + StringifyJs(&*module.module.ident().to_string().await?) + ) + .as_bytes(), + ); + + for &side_effect in self.module.await?.side_effects.await?.iter() { + if !has_top_level_await { + let async_module = *side_effect.get_async_module().await?; + if let Some(async_module) = async_module { + if async_module.await?.has_top_level_await { + has_top_level_await = true; + } + } + } + + code.push_bytes( + format!( + "__turbopack_import__({});\n", + StringifyJs(&*side_effect.ident().to_string().await?) + ) + .as_bytes(), + ); + } + + let code = code.build(); + + Ok(EcmascriptChunkItemContent { + inner_code: code, + source_map: None, + rewrite_source_path: None, + options: EcmascriptChunkItemOptions { + strict: true, + exports: true, + async_module: if has_top_level_await { + Some(AsyncModuleOptions { + has_top_level_await: true, + }) + } else { + None + }, + ..Default::default() + }, + placeholder_for_future_extensions: (), + } + .cell()) } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> {} + fn chunking_context(&self) -> Vc> { + self.chunking_context + } } From 2023694fb5091b681b7f851c29557e3f551a3ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 16:36:59 +0900 Subject: [PATCH 15/48] wrap_module_part_asset --- .../src/tree_shake/asset.rs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 6cd4f76c3b300..ea303053213f1 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -291,7 +291,10 @@ async fn follow_reexports_with_side_effects( .is_marked_as_side_effect_free(side_effect_free_packages) .await?; if ignore { - side_effects.push(current_module); + side_effects.push(wrap_module_part_asset( + current_module, + ModulePart::evaluation(), + )); } vdbg!(ignore, current_module.ident().to_string().await?); @@ -313,7 +316,7 @@ async fn follow_reexports_with_side_effects( match ty { FoundExportType::SideEffects => { - side_effects.push(*module); + side_effects.push(wrap_module_part_asset(*module, ModulePart::evaluation())); current_module = *module; current_export_name = export_name.clone().unwrap_or(current_export_name); } @@ -462,3 +465,20 @@ fn analyze( #[turbo_tasks::value_impl] impl EvaluatableAsset for EcmascriptModulePartAsset {} + +#[turbo_tasks::function] +async fn wrap_module_part_asset( + module: Vc>, + part: Vc, +) -> Result>> { + if let Some(module) = Vc::try_resolve_downcast_type::(module).await? { + let module = EcmascriptModulePartAsset::select_part(module, part); + if let Some(module) = + Vc::try_resolve_sidecast::>(module).await? + { + return Ok(module); + } + } + + Ok(module) +} From b914004548787721350b4a5776cd7a28f2adbdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 15 Oct 2024 16:54:47 +0900 Subject: [PATCH 16/48] new_name --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index ea303053213f1..446772b59a233 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -168,6 +168,8 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast( SideEffectsModule { + export_name: *export, + new_name: new_export.clone().map(|v| Vc::cell(v)), module: final_module, side_effects: Vc::cell(side_effects), } @@ -194,6 +196,8 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] pub(super) struct SideEffectsModule { pub module: Vc>, + pub export_name: Vc, + pub new_name: Option>, pub side_effects: Vc, } @@ -296,7 +300,6 @@ async fn follow_reexports_with_side_effects( ModulePart::evaluation(), )); } - vdbg!(ignore, current_module.ident().to_string().await?); // We ignore the side effect of the entry module here, because we need to proceed. let result = follow_reexports( @@ -312,8 +315,6 @@ async fn follow_reexports_with_side_effects( ty, } = &*result.await?; - vdbg!(ty, module.ident().to_string().await?); - match ty { FoundExportType::SideEffects => { side_effects.push(wrap_module_part_asset(*module, ModulePart::evaluation())); From 4c4fd1bf514bf47452cb3be4922d65f2192bf79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 12:40:44 +0900 Subject: [PATCH 17/48] Rename field --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 10 +++++----- .../turbopack-ecmascript/src/tree_shake/chunk_item.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 446772b59a233..04588f574d65b 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -170,7 +170,7 @@ impl EcmascriptModulePartAsset { SideEffectsModule { export_name: *export, new_name: new_export.clone().map(|v| Vc::cell(v)), - module: final_module, + binding: final_module, side_effects: Vc::cell(side_effects), } .cell(), @@ -195,7 +195,7 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] pub(super) struct SideEffectsModule { - pub module: Vc>, + pub binding: Vc>, pub export_name: Vc, pub new_name: Option>, pub side_effects: Vc, @@ -205,7 +205,7 @@ pub(super) struct SideEffectsModule { impl Module for SideEffectsModule { #[turbo_tasks::function] fn ident(&self) -> Vc { - self.module + self.binding .ident() .with_modifier(Vc::cell(RcStr::from("with intermediate side-effects"))) } @@ -222,7 +222,7 @@ impl Module for SideEffectsModule { } references.push(Vc::upcast(SingleModuleReference::new( - Vc::upcast(self.module), + Vc::upcast(self.binding), Vc::cell(RcStr::from("target binding")), ))); @@ -242,7 +242,7 @@ impl Asset for SideEffectsModule { impl EcmascriptChunkPlaceable for SideEffectsModule { #[turbo_tasks::function] async fn get_exports(&self) -> Vc { - self.module.get_exports() + self.binding.get_exports() } #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 4848fcec597e0..8b9bf954b4ae8 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -160,7 +160,7 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { code.push_bytes( format!( "__turbopack_export_namespace__(__turbopack_import__({}));\n", - StringifyJs(&*module.module.ident().to_string().await?) + StringifyJs(&*module.binding.ident().to_string().await?) ) .as_bytes(), ); From 96bf7e4f922bfb59b37527c5f0d4f555f6e94334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 13:00:07 +0900 Subject: [PATCH 18/48] order --- .../src/tree_shake/chunk_item.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 8b9bf954b4ae8..5d5b7d3c52f45 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -157,14 +157,6 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { let module = self.module.await?; - code.push_bytes( - format!( - "__turbopack_export_namespace__(__turbopack_import__({}));\n", - StringifyJs(&*module.binding.ident().to_string().await?) - ) - .as_bytes(), - ); - for &side_effect in self.module.await?.side_effects.await?.iter() { if !has_top_level_await { let async_module = *side_effect.get_async_module().await?; @@ -184,6 +176,14 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { ); } + code.push_bytes( + format!( + "__turbopack_export_namespace__(__turbopack_import__({}));\n", + StringifyJs(&*module.binding.ident().to_string().await?) + ) + .as_bytes(), + ); + let code = code.build(); Ok(EcmascriptChunkItemContent { From cbe54e04f9fa84a658c7eeb5381d9da3ee56dc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 14:28:35 +0900 Subject: [PATCH 19/48] Fix `SideEffectsModule::ident` --- .../src/tree_shake/asset.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 04588f574d65b..cd291a9cfac8c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{vdbg, ResolvedVc, ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, Value, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -204,10 +204,17 @@ pub(super) struct SideEffectsModule { #[turbo_tasks::value_impl] impl Module for SideEffectsModule { #[turbo_tasks::function] - fn ident(&self) -> Vc { - self.binding - .ident() - .with_modifier(Vc::cell(RcStr::from("with intermediate side-effects"))) + async fn ident(&self) -> Result> { + let mut ident = self.binding.ident().await?.clone_value(); + + for (i, side_effect) in self.side_effects.await?.iter().enumerate() { + ident.add_asset( + Vc::cell(RcStr::from(format!("side effect {}", i))), + side_effect.ident(), + ); + } + + Ok(AssetIdent::new(Value::new(ident))) } #[turbo_tasks::function] @@ -247,7 +254,7 @@ impl EcmascriptChunkPlaceable for SideEffectsModule { #[turbo_tasks::function] async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { - Vc::cell(false) + Vc::cell(true) } } From c25ef0fa1fdb948cd9471921699e5ca983666667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:00:42 +0900 Subject: [PATCH 20/48] modifier --- turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index cd291a9cfac8c..b17a8f326eb4c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -207,6 +207,8 @@ impl Module for SideEffectsModule { async fn ident(&self) -> Result> { let mut ident = self.binding.ident().await?.clone_value(); + ident.add_modifier(Vc::cell(RcStr::from("side effects"))); + for (i, side_effect) in self.side_effects.await?.iter().enumerate() { ident.add_asset( Vc::cell(RcStr::from(format!("side effect {}", i))), From d830b3576208074a09d35e75c407461391f8d5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:05:30 +0900 Subject: [PATCH 21/48] return original if no side effect --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index b17a8f326eb4c..d5323e0af9741 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -165,6 +165,9 @@ impl EcmascriptModulePartAsset { }; let side_effects = side_effects.await?.to_vec(); + if side_effects.is_empty() { + return Ok(Vc::upcast(final_module)); + } return Ok(Vc::upcast( SideEffectsModule { @@ -256,7 +259,7 @@ impl EcmascriptChunkPlaceable for SideEffectsModule { #[turbo_tasks::function] async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { - Vc::cell(true) + Vc::cell(false) } } From 7454c17d079c22b8ea73891037d202aa75e50cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:06:32 +0900 Subject: [PATCH 22/48] cleanup --- turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index d5323e0af9741..5d76f9bea0b6c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -171,8 +171,6 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast( SideEffectsModule { - export_name: *export, - new_name: new_export.clone().map(|v| Vc::cell(v)), binding: final_module, side_effects: Vc::cell(side_effects), } @@ -199,8 +197,6 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] pub(super) struct SideEffectsModule { pub binding: Vc>, - pub export_name: Vc, - pub new_name: Option>, pub side_effects: Vc, } From 340466b3563d2b6254c2447afdd8eb5583764dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:13:08 +0900 Subject: [PATCH 23/48] only_effects --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 5d76f9bea0b6c..a7d97434fd79a 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -303,10 +303,7 @@ async fn follow_reexports_with_side_effects( .is_marked_as_side_effect_free(side_effect_free_packages) .await?; if ignore { - side_effects.push(wrap_module_part_asset( - current_module, - ModulePart::evaluation(), - )); + side_effects.push(only_effects(current_module)); } // We ignore the side effect of the entry module here, because we need to proceed. @@ -325,7 +322,6 @@ async fn follow_reexports_with_side_effects( match ty { FoundExportType::SideEffects => { - side_effects.push(wrap_module_part_asset(*module, ModulePart::evaluation())); current_module = *module; current_export_name = export_name.clone().unwrap_or(current_export_name); } @@ -476,12 +472,11 @@ fn analyze( impl EvaluatableAsset for EcmascriptModulePartAsset {} #[turbo_tasks::function] -async fn wrap_module_part_asset( +async fn only_effects( module: Vc>, - part: Vc, ) -> Result>> { if let Some(module) = Vc::try_resolve_downcast_type::(module).await? { - let module = EcmascriptModulePartAsset::select_part(module, part); + let module = EcmascriptModulePartAsset::select_part(module, ModulePart::evaluation()); if let Some(module) = Vc::try_resolve_sidecast::>(module).await? { From 8bac483e2145e4accdb7c7e3f6ebe95b6d09b824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:20:08 +0900 Subject: [PATCH 24/48] need_await --- .../src/tree_shake/chunk_item.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 5d5b7d3c52f45..9ef0c6a42f957 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -158,18 +158,24 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { let module = self.module.await?; for &side_effect in self.module.await?.side_effects.await?.iter() { - if !has_top_level_await { + let need_await = 'need_await: { let async_module = *side_effect.get_async_module().await?; if let Some(async_module) = async_module { if async_module.await?.has_top_level_await { - has_top_level_await = true; + break 'need_await true; } } + false + }; + + if !has_top_level_await && need_await { + has_top_level_await = true; } code.push_bytes( format!( - "__turbopack_import__({});\n", + "{}__turbopack_import__({});\n", + if need_await { "await " } else { "" }, StringifyJs(&*side_effect.ident().to_string().await?) ) .as_bytes(), From cc6d01fd0962048ceac1cf002f6b5672d3e527b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Wed, 16 Oct 2024 15:27:54 +0900 Subject: [PATCH 25/48] cleanup --- .../src/tree_shake/asset.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index a7d97434fd79a..a87b8f1812948 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -119,18 +119,7 @@ impl EcmascriptModulePartAsset { let side_effect_free_packages = module.asset_context().side_effect_free_packages(); // Exclude local bindings by using exports module part. - let source_module = if entrypoints.contains_key(&Key::Exports) - && *module - .is_marked_as_side_effect_free(side_effect_free_packages) - .await? - { - Vc::upcast(EcmascriptModulePartAsset::new( - module, - ModulePart::exports(), - )) - } else { - Vc::upcast(module) - }; + let source_module = Vc::upcast(module); let FollowExportsWithSideEffectsResult { side_effects, @@ -299,10 +288,11 @@ async fn follow_reexports_with_side_effects( let mut current_module = module; let mut current_export_name = export_name; let result = loop { - let ignore = !*current_module + let is_side_effect_free = *current_module .is_marked_as_side_effect_free(side_effect_free_packages) .await?; - if ignore { + + if !is_side_effect_free { side_effects.push(only_effects(current_module)); } From 746a5044031953b2c409526fa6eef487251f9eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Thu, 31 Oct 2024 12:41:54 +0900 Subject: [PATCH 26/48] fix build --- turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs | 4 ++-- .../crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index a87b8f1812948..2d39e51279295 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -199,8 +199,8 @@ impl Module for SideEffectsModule { for (i, side_effect) in self.side_effects.await?.iter().enumerate() { ident.add_asset( - Vc::cell(RcStr::from(format!("side effect {}", i))), - side_effect.ident(), + ResolvedVc::cell(RcStr::from(format!("side effect {}", i))), + side_effect.ident().to_resolved().await?, ); } diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 9ef0c6a42f957..5a10a063e794c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -208,6 +208,7 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { }, ..Default::default() }, + rewrite_source_path: None, placeholder_for_future_extensions: (), } .cell()) From 552ca7e9d5718cf7ecc4ba209534dc6772029e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Fri, 8 Nov 2024 14:39:55 +0900 Subject: [PATCH 27/48] [TRY] Eager drop of references --- .../crates/turbopack-ecmascript/src/references/mod.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index 53035699c20c7..f82a514a006a3 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -57,6 +57,7 @@ use turbopack_core::{ compile_time_info::{ CompileTimeInfo, DefineableNameSegment, FreeVarReference, FreeVarReferences, }, + context::AssetContext, environment::Rendering, error::PrettyPrintError, issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, @@ -124,7 +125,7 @@ use crate::{ top_level_await::has_top_level_await, ConstantNumber, ConstantString, JsValueUrlKind, RequireContextValue, }, - chunk::EcmascriptExports, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGen, CodeGenerateable, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables}, magic_identifier, parse::parse, @@ -591,6 +592,10 @@ pub(crate) async fn analyse_ecmascript_module_internal( set_handler_and_globals(&handler, globals, || create_graph(program, eval_context)); let mut evaluation_references = Vec::new(); + let side_effect_free_packages = module.asset_context().side_effect_free_packages(); + let is_side_effect_free = *module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await?; for (i, r) in eval_context.imports.references().enumerate() { let r = EsmAssetReference::new( @@ -607,7 +612,9 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), ImportedSymbol::PartEvaluation(part_id) => { - evaluation_references.push(i); + if !is_side_effect_free { + evaluation_references.push(i); + } Some(ModulePart::internal_evaluation(*part_id)) } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), From 475190c028341d55fc0632e031973d2307d5674c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Tue, 12 Nov 2024 13:26:49 +0900 Subject: [PATCH 28/48] Remove variant related codes --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 6 +++++- .../turbopack-ecmascript/src/tree_shake/chunk_item.rs | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 2d39e51279295..1928532cdca0e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, Value, Vc}; +use turbo_tasks::{vdbg, ResolvedVc, Value, ValueToString, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -106,6 +106,8 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast(module)); }; + vdbg!(module.ident().to_string(), part); + // We follow reexports here if let ModulePart::Export(export) = &*part.await? { let export_name = export.await?.clone_value(); @@ -416,6 +418,8 @@ impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { ) -> Result> { let this = self.await?; + vdbg!(self.ident().to_string()); + match *this.part.await? { ModulePart::Exports | ModulePart::Export(..) => Ok(Vc::cell(true)), _ => Ok(this diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 5a10a063e794c..9ef0c6a42f957 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -208,7 +208,6 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { }, ..Default::default() }, - rewrite_source_path: None, placeholder_for_future_extensions: (), } .cell()) From 3a742d052a8da42ca133bcfd8ac0302093c2d3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Thu, 14 Nov 2024 12:28:25 +0900 Subject: [PATCH 29/48] Fix lints --- .../turbopack-ecmascript/src/references/esm/export.rs | 2 -- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 1f667142d4c35..8ea7e0fd87f94 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -25,7 +25,6 @@ use turbopack_core::{ issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, StyledString}, module::Module, reference::ModuleReference, - resolve::ModulePart, }; use super::base::ReferencedAsset; @@ -33,7 +32,6 @@ use crate::{ chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGenerateable, CodeGeneration, CodeGenerationHoistedStmt}, magic_identifier, - tree_shake::asset::EcmascriptModulePartAsset, }; #[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 1928532cdca0e..2d39e51279295 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{vdbg, ResolvedVc, Value, ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, Value, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -106,8 +106,6 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast(module)); }; - vdbg!(module.ident().to_string(), part); - // We follow reexports here if let ModulePart::Export(export) = &*part.await? { let export_name = export.await?.clone_value(); @@ -418,8 +416,6 @@ impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { ) -> Result> { let this = self.await?; - vdbg!(self.ident().to_string()); - match *this.part.await? { ModulePart::Exports | ModulePart::Export(..) => Ok(Vc::cell(true)), _ => Ok(this From da42e00d3640b239458a0700f294cc35512106bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Thu, 14 Nov 2024 16:29:36 +0900 Subject: [PATCH 30/48] Improve `SideEffectsModule::ident()` --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 2d39e51279295..96db998eeba68 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -193,7 +193,13 @@ pub(super) struct SideEffectsModule { impl Module for SideEffectsModule { #[turbo_tasks::function] async fn ident(&self) -> Result> { - let mut ident = self.binding.ident().await?.clone_value(); + let path = self.binding.ident().path(); + let mut ident = AssetIdent::from_path(path).await?.clone_value(); + + ident.add_asset( + ResolvedVc::cell(RcStr::from("binding")), + self.binding.ident().to_resolved().await?, + ); ident.add_modifier(Vc::cell(RcStr::from("side effects"))); From a1ad06154271743e057ef0e4cd46cbebbaed9d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Thu, 14 Nov 2024 16:35:42 +0900 Subject: [PATCH 31/48] Use original module ident --- .../src/tree_shake/asset.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 96db998eeba68..8a532627e5594 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -100,7 +100,7 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::function] pub async fn select_part( module: Vc, - part: Vc, + part: ResolvedVc, ) -> Result>> { let SplitResult::Ok { entrypoints, .. } = &*split_module(module).await? else { return Ok(Vc::upcast(module)); @@ -113,7 +113,7 @@ impl EcmascriptModulePartAsset { // If a local binding or reexport with the same name exists, we stop here. // Side effects of the barrel file are preserved. if entrypoints.contains_key(&Key::Export(export_name.clone())) { - return Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, part))); + return Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, *part))); } let side_effect_free_packages = module.asset_context().side_effect_free_packages(); @@ -160,6 +160,8 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast( SideEffectsModule { + module, + part, binding: final_module, side_effects: Vc::cell(side_effects), } @@ -167,7 +169,7 @@ impl EcmascriptModulePartAsset { )); } - Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, part))) + Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, *part))) } #[turbo_tasks::function] @@ -185,6 +187,10 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] pub(super) struct SideEffectsModule { + /// Original module + module: Vc, + /// The part of the original module that is the binding + part: ResolvedVc, pub binding: Vc>, pub side_effects: Vc, } @@ -193,11 +199,11 @@ pub(super) struct SideEffectsModule { impl Module for SideEffectsModule { #[turbo_tasks::function] async fn ident(&self) -> Result> { - let path = self.binding.ident().path(); - let mut ident = AssetIdent::from_path(path).await?.clone_value(); + let mut ident = self.module.ident().await?.clone_value(); + ident.parts.push(self.part); ident.add_asset( - ResolvedVc::cell(RcStr::from("binding")), + ResolvedVc::cell(RcStr::from("resolved")), self.binding.ident().to_resolved().await?, ); From b5c5582bd2040679cf2853119ef8025e3f22a684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Thu, 14 Nov 2024 16:38:10 +0900 Subject: [PATCH 32/48] Rename fields --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 12 +++++++----- .../src/tree_shake/chunk_item.rs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 8a532627e5594..4ee5903865b03 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -162,7 +162,7 @@ impl EcmascriptModulePartAsset { SideEffectsModule { module, part, - binding: final_module, + resolved_as: final_module, side_effects: Vc::cell(side_effects), } .cell(), @@ -191,7 +191,9 @@ pub(super) struct SideEffectsModule { module: Vc, /// The part of the original module that is the binding part: ResolvedVc, - pub binding: Vc>, + /// The module that is the binding + pub resolved_as: Vc>, + /// Side effects from the original module to the binding. pub side_effects: Vc, } @@ -204,7 +206,7 @@ impl Module for SideEffectsModule { ident.add_asset( ResolvedVc::cell(RcStr::from("resolved")), - self.binding.ident().to_resolved().await?, + self.resolved_as.ident().to_resolved().await?, ); ident.add_modifier(Vc::cell(RcStr::from("side effects"))); @@ -231,7 +233,7 @@ impl Module for SideEffectsModule { } references.push(Vc::upcast(SingleModuleReference::new( - Vc::upcast(self.binding), + Vc::upcast(self.resolved_as), Vc::cell(RcStr::from("target binding")), ))); @@ -251,7 +253,7 @@ impl Asset for SideEffectsModule { impl EcmascriptChunkPlaceable for SideEffectsModule { #[turbo_tasks::function] async fn get_exports(&self) -> Vc { - self.binding.get_exports() + self.resolved_as.get_exports() } #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 9ef0c6a42f957..3a05852e9ddef 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -185,7 +185,7 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { code.push_bytes( format!( "__turbopack_export_namespace__(__turbopack_import__({}));\n", - StringifyJs(&*module.binding.ident().to_string().await?) + StringifyJs(&*module.resolved_as.ident().to_string().await?) ) .as_bytes(), ); From f527368de3c72ebb4cceb61a74d4dfcdbbbd79c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Fri, 15 Nov 2024 15:47:47 +0900 Subject: [PATCH 33/48] SingleChunkableModuleReference --- .../turbopack-core/src/reference/mod.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/turbopack/crates/turbopack-core/src/reference/mod.rs b/turbopack/crates/turbopack-core/src/reference/mod.rs index 7f47d085c0268..70fd893ea4905 100644 --- a/turbopack/crates/turbopack-core/src/reference/mod.rs +++ b/turbopack/crates/turbopack-core/src/reference/mod.rs @@ -8,6 +8,7 @@ use turbo_tasks::{ }; use crate::{ + chunk::{ChunkableModuleReference, ChunkingType, ChunkingTypeOption}, issue::IssueDescriptionExt, module::{Module, Modules}, output::{OutputAsset, OutputAssets}, @@ -84,6 +85,44 @@ impl SingleModuleReference { } } +#[turbo_tasks::value] +pub struct SingleChunkableModuleReference { + asset: ResolvedVc>, + description: Vc, +} + +#[turbo_tasks::value_impl] +impl SingleChunkableModuleReference { + #[turbo_tasks::function] + pub fn new(asset: ResolvedVc>, description: Vc) -> Vc { + Self::cell(SingleChunkableModuleReference { asset, description }) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for SingleChunkableModuleReference { + #[turbo_tasks::function] + fn chunking_type(self: Vc) -> Vc { + Vc::cell(Some(ChunkingType::ParallelInheritAsync)) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for SingleChunkableModuleReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(self.asset).cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for SingleChunkableModuleReference { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + self.description + } +} + /// A reference that always resolves to a single module. #[turbo_tasks::value] pub struct SingleOutputAssetReference { From 66345c2cbe18b0030a94b11edd53f381984b2f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Fri, 15 Nov 2024 15:48:34 +0900 Subject: [PATCH 34/48] Done --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 4ee5903865b03..8e19fe19c7bef 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -8,7 +8,9 @@ use turbopack_core::{ context::AssetContext, ident::AssetIdent, module::Module, - reference::{ModuleReference, ModuleReferences, SingleModuleReference}, + reference::{ + ModuleReference, ModuleReferences, SingleChunkableModuleReference, SingleModuleReference, + }, resolve::{origin::ResolveOrigin, ModulePart}, }; @@ -226,15 +228,15 @@ impl Module for SideEffectsModule { let mut references = vec![]; for &side_effect in self.side_effects.await?.iter() { - references.push(Vc::upcast(SingleModuleReference::new( + references.push(Vc::upcast(SingleChunkableModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), ))); } - references.push(Vc::upcast(SingleModuleReference::new( + references.push(Vc::upcast(SingleChunkableModuleReference::new( Vc::upcast(self.resolved_as), - Vc::cell(RcStr::from("target binding")), + Vc::cell(RcStr::from("resolved as")), ))); Ok(Vc::cell(references)) From ba2b3b465c12a8e0bb9b5524baf71f8ff7317955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 11:17:59 +0900 Subject: [PATCH 35/48] Remove hack --- .../crates/turbopack-ecmascript/src/references/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index f82a514a006a3..c13eb445ff6da 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -592,10 +592,6 @@ pub(crate) async fn analyse_ecmascript_module_internal( set_handler_and_globals(&handler, globals, || create_graph(program, eval_context)); let mut evaluation_references = Vec::new(); - let side_effect_free_packages = module.asset_context().side_effect_free_packages(); - let is_side_effect_free = *module - .is_marked_as_side_effect_free(side_effect_free_packages) - .await?; for (i, r) in eval_context.imports.references().enumerate() { let r = EsmAssetReference::new( @@ -612,9 +608,6 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), ImportedSymbol::PartEvaluation(part_id) => { - if !is_side_effect_free { - evaluation_references.push(i); - } Some(ModulePart::internal_evaluation(*part_id)) } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), From 0ee594573f953c47bc93d87192fdd44e3e7c77e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 11:24:29 +0900 Subject: [PATCH 36/48] revert --- turbopack/crates/turbopack-ecmascript/src/references/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index c13eb445ff6da..53035699c20c7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -57,7 +57,6 @@ use turbopack_core::{ compile_time_info::{ CompileTimeInfo, DefineableNameSegment, FreeVarReference, FreeVarReferences, }, - context::AssetContext, environment::Rendering, error::PrettyPrintError, issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, @@ -125,7 +124,7 @@ use crate::{ top_level_await::has_top_level_await, ConstantNumber, ConstantString, JsValueUrlKind, RequireContextValue, }, - chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + chunk::EcmascriptExports, code_gen::{CodeGen, CodeGenerateable, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables}, magic_identifier, parse::parse, @@ -608,6 +607,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), ImportedSymbol::PartEvaluation(part_id) => { + evaluation_references.push(i); Some(ModulePart::internal_evaluation(*part_id)) } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), From cf779a187c080d1015eb48473e3b301338295b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 11:27:34 +0900 Subject: [PATCH 37/48] review feedback --- .../turbopack-ecmascript/src/references/esm/export.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 8ea7e0fd87f94..eed3a0acc5fbe 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -156,13 +156,8 @@ pub async fn follow_reexports( // Try to find the export in the local exports let exports_ref = exports.await?; if let Some(export) = exports_ref.exports.get(&export_name) { - match handle_declared_export( - module, - export_name.clone(), - export, - side_effect_free_packages, - ) - .await? + match handle_declared_export(module, export_name, export, side_effect_free_packages) + .await? { ControlFlow::Continue((m, n)) => { module = m; From 903a1d81a5fec0909691ff01178e2d2ee74477fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 11:40:41 +0900 Subject: [PATCH 38/48] is_marked_as_side_effect_free --- .../src/tree_shake/asset.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 8e19fe19c7bef..2eee6bfcf1716 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -160,15 +160,15 @@ impl EcmascriptModulePartAsset { return Ok(Vc::upcast(final_module)); } - return Ok(Vc::upcast( - SideEffectsModule { - module, - part, - resolved_as: final_module, - side_effects: Vc::cell(side_effects), - } - .cell(), - )); + let side_effects_module = SideEffectsModule { + module, + part, + resolved_as: final_module, + side_effects: Vc::cell(side_effects), + } + .cell(); + + return Ok(Vc::upcast(side_effects_module)); } Ok(Vc::upcast(EcmascriptModulePartAsset::new(module, *part))) @@ -260,7 +260,7 @@ impl EcmascriptChunkPlaceable for SideEffectsModule { #[turbo_tasks::function] async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { - Vc::cell(false) + Vc::cell(true) } } From a9959e65988403df9f2e4c86c023879a8211c47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 12:02:08 +0900 Subject: [PATCH 39/48] Fix test by using a hack --- .../crates/turbopack-ecmascript/src/references/mod.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index 53035699c20c7..f82a514a006a3 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -57,6 +57,7 @@ use turbopack_core::{ compile_time_info::{ CompileTimeInfo, DefineableNameSegment, FreeVarReference, FreeVarReferences, }, + context::AssetContext, environment::Rendering, error::PrettyPrintError, issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, @@ -124,7 +125,7 @@ use crate::{ top_level_await::has_top_level_await, ConstantNumber, ConstantString, JsValueUrlKind, RequireContextValue, }, - chunk::EcmascriptExports, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGen, CodeGenerateable, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables}, magic_identifier, parse::parse, @@ -591,6 +592,10 @@ pub(crate) async fn analyse_ecmascript_module_internal( set_handler_and_globals(&handler, globals, || create_graph(program, eval_context)); let mut evaluation_references = Vec::new(); + let side_effect_free_packages = module.asset_context().side_effect_free_packages(); + let is_side_effect_free = *module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await?; for (i, r) in eval_context.imports.references().enumerate() { let r = EsmAssetReference::new( @@ -607,7 +612,9 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), ImportedSymbol::PartEvaluation(part_id) => { - evaluation_references.push(i); + if !is_side_effect_free { + evaluation_references.push(i); + } Some(ModulePart::internal_evaluation(*part_id)) } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), From 6c80e23470687aeaf13bfb86653fc655dedbef66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 12:07:30 +0900 Subject: [PATCH 40/48] Split file --- .../src/tree_shake/asset.rs | 117 +--------------- .../src/tree_shake/chunk_item.rs | 2 +- .../src/tree_shake/mod.rs | 1 + .../src/tree_shake/side_effect_module.rs | 132 ++++++++++++++++++ 4 files changed, 140 insertions(+), 112 deletions(-) create mode 100644 turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 2eee6bfcf1716..609e00434b433 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use turbo_rcstr::RcStr; -use turbo_tasks::{ResolvedVc, Value, Vc}; +use turbo_tasks::{ResolvedVc, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -8,9 +8,7 @@ use turbopack_core::{ context::AssetContext, ident::AssetIdent, module::Module, - reference::{ - ModuleReference, ModuleReferences, SingleChunkableModuleReference, SingleModuleReference, - }, + reference::{ModuleReference, ModuleReferences, SingleModuleReference}, resolve::{origin::ResolveOrigin, ModulePart}, }; @@ -25,7 +23,7 @@ use crate::{ analyse_ecmascript_module, esm::FoundExportType, follow_reexports, FollowExportsResult, }, side_effect_optimization::facade::module::EcmascriptModuleFacadeModule, - tree_shake::{chunk_item::SideEffectsModuleChunkItem, Key}, + tree_shake::{side_effect_module::SideEffectsModule, Key}, AnalyzeEcmascriptModuleResult, EcmascriptAnalyzable, EcmascriptModuleAsset, EcmascriptModuleAssetType, EcmascriptModuleContent, EcmascriptParsable, }; @@ -155,18 +153,12 @@ impl EcmascriptModulePartAsset { )) }; - let side_effects = side_effects.await?.to_vec(); - if side_effects.is_empty() { + if side_effects.await?.is_empty() { return Ok(Vc::upcast(final_module)); } - let side_effects_module = SideEffectsModule { - module, - part, - resolved_as: final_module, - side_effects: Vc::cell(side_effects), - } - .cell(); + let side_effects_module = + SideEffectsModule::new(module, part, final_module, *side_effects); return Ok(Vc::upcast(side_effects_module)); } @@ -187,103 +179,6 @@ impl EcmascriptModulePartAsset { } } -#[turbo_tasks::value] -pub(super) struct SideEffectsModule { - /// Original module - module: Vc, - /// The part of the original module that is the binding - part: ResolvedVc, - /// The module that is the binding - pub resolved_as: Vc>, - /// Side effects from the original module to the binding. - pub side_effects: Vc, -} - -#[turbo_tasks::value_impl] -impl Module for SideEffectsModule { - #[turbo_tasks::function] - async fn ident(&self) -> Result> { - let mut ident = self.module.ident().await?.clone_value(); - ident.parts.push(self.part); - - ident.add_asset( - ResolvedVc::cell(RcStr::from("resolved")), - self.resolved_as.ident().to_resolved().await?, - ); - - ident.add_modifier(Vc::cell(RcStr::from("side effects"))); - - for (i, side_effect) in self.side_effects.await?.iter().enumerate() { - ident.add_asset( - ResolvedVc::cell(RcStr::from(format!("side effect {}", i))), - side_effect.ident().to_resolved().await?, - ); - } - - Ok(AssetIdent::new(Value::new(ident))) - } - - #[turbo_tasks::function] - async fn references(&self) -> Result> { - let mut references = vec![]; - - for &side_effect in self.side_effects.await?.iter() { - references.push(Vc::upcast(SingleChunkableModuleReference::new( - Vc::upcast(side_effect), - Vc::cell(RcStr::from("side effect")), - ))); - } - - references.push(Vc::upcast(SingleChunkableModuleReference::new( - Vc::upcast(self.resolved_as), - Vc::cell(RcStr::from("resolved as")), - ))); - - Ok(Vc::cell(references)) - } -} - -#[turbo_tasks::value_impl] -impl Asset for SideEffectsModule { - #[turbo_tasks::function] - fn content(&self) -> Vc { - unreachable!("SideEffectsModule has no content") - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for SideEffectsModule { - #[turbo_tasks::function] - async fn get_exports(&self) -> Vc { - self.resolved_as.get_exports() - } - - #[turbo_tasks::function] - async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { - Vc::cell(true) - } -} - -#[turbo_tasks::value_impl] -impl ChunkableModule for SideEffectsModule { - #[turbo_tasks::function] - async fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Result>> { - Ok(Vc::upcast( - SideEffectsModuleChunkItem { - module: self, - chunking_context, - } - .cell(), - )) - } -} - -#[turbo_tasks::value_impl] -impl EvaluatableAsset for SideEffectsModule {} - #[turbo_tasks::value] struct FollowExportsWithSideEffectsResult { side_effects: Vc, diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 3a05852e9ddef..02db1ebc184e6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -15,7 +15,7 @@ use crate::{ EcmascriptChunkPlaceable, EcmascriptChunkType, }, references::async_module::AsyncModuleOptions, - tree_shake::asset::SideEffectsModule, + tree_shake::side_effect_module::SideEffectsModule, utils::StringifyJs, EcmascriptModuleContent, }; diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs index b64043161a6c0..6b1fd7d82346f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -27,6 +27,7 @@ pub mod chunk_item; mod graph; pub mod merge; mod optimizations; +mod side_effect_module; #[cfg(test)] mod tests; mod util; diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs new file mode 100644 index 0000000000000..27f46617cfc22 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs @@ -0,0 +1,132 @@ +use anyhow::Result; +use turbo_rcstr::RcStr; +use turbo_tasks::{ResolvedVc, Value, Vc}; +use turbo_tasks_fs::glob::Glob; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset}, + ident::AssetIdent, + module::Module, + reference::{ModuleReferences, SingleChunkableModuleReference}, + resolve::ModulePart, +}; + +use crate::{ + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + tree_shake::{asset::SideEffects, chunk_item::SideEffectsModuleChunkItem}, + EcmascriptModuleAsset, +}; + +#[turbo_tasks::value] +pub(super) struct SideEffectsModule { + /// Original module + pub module: Vc, + /// The part of the original module that is the binding + pub part: ResolvedVc, + /// The module that is the binding + pub resolved_as: Vc>, + /// Side effects from the original module to the binding. + pub side_effects: Vc, +} + +impl SideEffectsModule { + pub fn new( + module: Vc, + part: ResolvedVc, + resolved_as: Vc>, + side_effects: Vc, + ) -> Vc { + SideEffectsModule { + module, + part, + resolved_as, + side_effects, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl Module for SideEffectsModule { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let mut ident = self.module.ident().await?.clone_value(); + ident.parts.push(self.part); + + ident.add_asset( + ResolvedVc::cell(RcStr::from("resolved")), + self.resolved_as.ident().to_resolved().await?, + ); + + ident.add_modifier(Vc::cell(RcStr::from("side effects"))); + + for (i, side_effect) in self.side_effects.await?.iter().enumerate() { + ident.add_asset( + ResolvedVc::cell(RcStr::from(format!("side effect {}", i))), + side_effect.ident().to_resolved().await?, + ); + } + + Ok(AssetIdent::new(Value::new(ident))) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let mut references = vec![]; + + for &side_effect in self.side_effects.await?.iter() { + references.push(Vc::upcast(SingleChunkableModuleReference::new( + Vc::upcast(side_effect), + Vc::cell(RcStr::from("side effect")), + ))); + } + + references.push(Vc::upcast(SingleChunkableModuleReference::new( + Vc::upcast(self.resolved_as), + Vc::cell(RcStr::from("resolved as")), + ))); + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for SideEffectsModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + unreachable!("SideEffectsModule has no content") + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for SideEffectsModule { + #[turbo_tasks::function] + async fn get_exports(&self) -> Vc { + self.resolved_as.get_exports() + } + + #[turbo_tasks::function] + async fn is_marked_as_side_effect_free(self: Vc, _: Vc) -> Vc { + Vc::cell(true) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for SideEffectsModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + SideEffectsModuleChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EvaluatableAsset for SideEffectsModule {} From 7c679f2aa582cdde6f12f21523418da6b4cca3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 12:09:57 +0900 Subject: [PATCH 41/48] No vc --- .../turbopack-ecmascript/src/tree_shake/asset.rs | 11 ++++------- .../src/tree_shake/chunk_item.rs | 2 +- .../src/tree_shake/side_effect_module.rs | 12 +++++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 609e00434b433..b7bbd399d090e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -153,12 +153,12 @@ impl EcmascriptModulePartAsset { )) }; - if side_effects.await?.is_empty() { + if side_effects.is_empty() { return Ok(Vc::upcast(final_module)); } let side_effects_module = - SideEffectsModule::new(module, part, final_module, *side_effects); + SideEffectsModule::new(module, *part, final_module, side_effects.to_vec()); return Ok(Vc::upcast(side_effects_module)); } @@ -181,13 +181,10 @@ impl EcmascriptModulePartAsset { #[turbo_tasks::value] struct FollowExportsWithSideEffectsResult { - side_effects: Vc, + side_effects: Vec>>, result: Vc, } -#[turbo_tasks::value(transparent)] -pub(super) struct SideEffects(pub Vec>>); - #[turbo_tasks::function] async fn follow_reexports_with_side_effects( module: Vc>, @@ -231,7 +228,7 @@ async fn follow_reexports_with_side_effects( }; Ok(FollowExportsWithSideEffectsResult { - side_effects: Vc::cell(side_effects), + side_effects, result, } .cell()) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 02db1ebc184e6..61d37da9093a2 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -157,7 +157,7 @@ impl EcmascriptChunkItem for SideEffectsModuleChunkItem { let module = self.module.await?; - for &side_effect in self.module.await?.side_effects.await?.iter() { + for &side_effect in self.module.await?.side_effects.iter() { let need_await = 'need_await: { let async_module = *side_effect.get_async_module().await?; if let Some(async_module) = async_module { diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs index 27f46617cfc22..a25f9de244b9e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/side_effect_module.rs @@ -13,7 +13,7 @@ use turbopack_core::{ use crate::{ chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, - tree_shake::{asset::SideEffects, chunk_item::SideEffectsModuleChunkItem}, + tree_shake::chunk_item::SideEffectsModuleChunkItem, EcmascriptModuleAsset, }; @@ -26,15 +26,17 @@ pub(super) struct SideEffectsModule { /// The module that is the binding pub resolved_as: Vc>, /// Side effects from the original module to the binding. - pub side_effects: Vc, + pub side_effects: Vec>>, } +#[turbo_tasks::value_impl] impl SideEffectsModule { + #[turbo_tasks::function] pub fn new( module: Vc, part: ResolvedVc, resolved_as: Vc>, - side_effects: Vc, + side_effects: Vec>>, ) -> Vc { SideEffectsModule { module, @@ -60,7 +62,7 @@ impl Module for SideEffectsModule { ident.add_modifier(Vc::cell(RcStr::from("side effects"))); - for (i, side_effect) in self.side_effects.await?.iter().enumerate() { + for (i, side_effect) in self.side_effects.iter().enumerate() { ident.add_asset( ResolvedVc::cell(RcStr::from(format!("side effect {}", i))), side_effect.ident().to_resolved().await?, @@ -74,7 +76,7 @@ impl Module for SideEffectsModule { async fn references(&self) -> Result> { let mut references = vec![]; - for &side_effect in self.side_effects.await?.iter() { + for &side_effect in self.side_effects.iter() { references.push(Vc::upcast(SingleChunkableModuleReference::new( Vc::upcast(side_effect), Vc::cell(RcStr::from("side effect")), From 80f6d06e1b160899cb8eca55c17ea3ab2f341226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 12:18:01 +0900 Subject: [PATCH 42/48] pub --- turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs index 6b1fd7d82346f..4f2caed87ff1d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -27,7 +27,7 @@ pub mod chunk_item; mod graph; pub mod merge; mod optimizations; -mod side_effect_module; +pub mod side_effect_module; #[cfg(test)] mod tests; mod util; From 8ea90fbd86770af8c0e3a897e9868016b68f3aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 15:34:29 +0900 Subject: [PATCH 43/48] Remove hack --- .../crates/turbopack-ecmascript/src/references/mod.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index f82a514a006a3..53035699c20c7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -57,7 +57,6 @@ use turbopack_core::{ compile_time_info::{ CompileTimeInfo, DefineableNameSegment, FreeVarReference, FreeVarReferences, }, - context::AssetContext, environment::Rendering, error::PrettyPrintError, issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, @@ -125,7 +124,7 @@ use crate::{ top_level_await::has_top_level_await, ConstantNumber, ConstantString, JsValueUrlKind, RequireContextValue, }, - chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + chunk::EcmascriptExports, code_gen::{CodeGen, CodeGenerateable, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables}, magic_identifier, parse::parse, @@ -592,10 +591,6 @@ pub(crate) async fn analyse_ecmascript_module_internal( set_handler_and_globals(&handler, globals, || create_graph(program, eval_context)); let mut evaluation_references = Vec::new(); - let side_effect_free_packages = module.asset_context().side_effect_free_packages(); - let is_side_effect_free = *module - .is_marked_as_side_effect_free(side_effect_free_packages) - .await?; for (i, r) in eval_context.imports.references().enumerate() { let r = EsmAssetReference::new( @@ -612,9 +607,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), ImportedSymbol::PartEvaluation(part_id) => { - if !is_side_effect_free { - evaluation_references.push(i); - } + evaluation_references.push(i); Some(ModulePart::internal_evaluation(*part_id)) } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), From 06966898878228eefa56bc753fc8d50a8d09b176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 15:41:00 +0900 Subject: [PATCH 44/48] Disable cargo test --- .../turbopack/tree-shaking/{basic => .basic}/input/index.js | 0 .../turbopack/tree-shaking/{basic => .basic}/options.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{basic => .basic}/input/index.js (100%) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{basic => .basic}/options.json (100%) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json From a4ee92693f26ff1b72d5ff82728672817831e716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 16:08:57 +0900 Subject: [PATCH 45/48] select_part --- .../crates/turbopack-ecmascript/src/tree_shake/asset.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index b7bbd399d090e..b365a24c19b39 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -374,12 +374,8 @@ async fn only_effects( module: Vc>, ) -> Result>> { if let Some(module) = Vc::try_resolve_downcast_type::(module).await? { - let module = EcmascriptModulePartAsset::select_part(module, ModulePart::evaluation()); - if let Some(module) = - Vc::try_resolve_sidecast::>(module).await? - { - return Ok(module); - } + let module = EcmascriptModulePartAsset::new(module, ModulePart::evaluation()); + return Ok(Vc::upcast(module)); } Ok(module) From f5dbb84466dff4f3587e43212be8123c5263b704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 18:49:11 +0900 Subject: [PATCH 46/48] Revert "Disable cargo test" This reverts commit 06966898878228eefa56bc753fc8d50a8d09b176. --- .../turbopack/tree-shaking/{.basic => basic}/input/index.js | 0 .../turbopack/tree-shaking/{.basic => basic}/options.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{.basic => basic}/input/index.js (100%) rename turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/{.basic => basic}/options.json (100%) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/input/index.js diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json similarity index 100% rename from turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json rename to turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/basic/options.json From dadb4f50fe70a8a15dd38a96a3997adce5150a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 20:25:16 +0900 Subject: [PATCH 47/48] Use module part for source module of follow_reexports --- turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index b365a24c19b39..63d178c6bd50e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -119,7 +119,7 @@ impl EcmascriptModulePartAsset { let side_effect_free_packages = module.asset_context().side_effect_free_packages(); // Exclude local bindings by using exports module part. - let source_module = Vc::upcast(module); + let source_module = Vc::upcast(EcmascriptModulePartAsset::new(module, *part)); let FollowExportsWithSideEffectsResult { side_effects, From 9a209c36f02743d01b1d98a280e51833cf4b607c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 18 Nov 2024 20:26:27 +0900 Subject: [PATCH 48/48] Use `EcmascriptModulePartAsset::new` when not required --- .../crates/turbopack-ecmascript/src/references/esm/base.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 46559061626cb..7499e4e28efe1 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -167,11 +167,11 @@ impl ModuleReference for EsmAssetReference { .await? .expect("EsmAssetReference origin should be a EcmascriptModuleAsset"); - return Ok(ModuleResolveResult::module( - EcmascriptModulePartAsset::select_part(*module, *part) + return Ok(ModuleResolveResult::module(ResolvedVc::upcast( + EcmascriptModulePartAsset::new(*module, *part) .to_resolved() .await?, - ) + )) .cell()); }