From 3cd345ec6bcf58bfa0272813c6f3a06e48d38562 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, 24 Sep 2024 10:12:34 +0900 Subject: [PATCH 01/10] star reexports --- crates/next-api/src/server_actions.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/next-api/src/server_actions.rs b/crates/next-api/src/server_actions.rs index 7463586569f2d..cec7d061d4b6d 100644 --- a/crates/next-api/src/server_actions.rs +++ b/crates/next-api/src/server_actions.rs @@ -294,6 +294,7 @@ async fn parse_actions(module: Vc>) -> Result Date: Tue, 24 Sep 2024 10:20:01 +0900 Subject: [PATCH 02/10] Merge more --- turbopack/crates/turbopack-core/src/ident.rs | 8 ++- .../crates/turbopack-core/src/resolve/mod.rs | 20 ++++++- .../src/analyzer/imports.rs | 42 +++++++++++++- .../src/references/esm/base.rs | 40 +++++++------ .../src/references/mod.rs | 17 +++++- .../side_effect_optimization/facade/module.rs | 9 +++ .../src/side_effect_optimization/reference.rs | 3 +- .../src/tree_shake/asset.rs | 24 +++++--- .../src/tree_shake/graph.rs | 57 ++++++++++++++----- .../src/tree_shake/mod.rs | 45 ++++++++------- turbopack/crates/turbopack/src/lib.rs | 13 +++-- 11 files changed, 204 insertions(+), 74 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/ident.rs b/turbopack/crates/turbopack-core/src/ident.rs index 4bb9d3964fa0e..fcb64a728e2ae 100644 --- a/turbopack/crates/turbopack-core/src/ident.rs +++ b/turbopack/crates/turbopack-core/src/ident.rs @@ -261,9 +261,10 @@ impl AssetIdent { ModulePart::Evaluation => { 1_u8.deterministic_hash(&mut hasher); } - ModulePart::Export(export) => { + ModulePart::Export(export, is_proxy) => { 2_u8.deterministic_hash(&mut hasher); export.await?.deterministic_hash(&mut hasher); + is_proxy.await?.deterministic_hash(&mut hasher); } ModulePart::RenamedExport { original_export, @@ -287,9 +288,12 @@ impl AssetIdent { ModulePart::Exports => { 7_u8.deterministic_hash(&mut hasher); } - ModulePart::Facade => { + ModulePart::StarReexports => { 8_u8.deterministic_hash(&mut hasher); } + ModulePart::Facade => { + 9_u8.deterministic_hash(&mut hasher); + } } has_hash = true; diff --git a/turbopack/crates/turbopack-core/src/resolve/mod.rs b/turbopack/crates/turbopack-core/src/resolve/mod.rs index 19d36b4153b6d..b8481d16f3c58 100644 --- a/turbopack/crates/turbopack-core/src/resolve/mod.rs +++ b/turbopack/crates/turbopack-core/src/resolve/mod.rs @@ -2862,7 +2862,10 @@ pub enum ModulePart { /// all exports are unused. Evaluation, /// Represents an export of a module. - Export(Vc), + /// + /// + /// bool value is true if it's proxied for `export * from './foo'` + Export(Vc, Vc), /// Represents a renamed export of a module. RenamedExport { original_export: Vc, @@ -2876,6 +2879,8 @@ pub enum ModulePart { Locals, /// The whole exports of a module. Exports, + /// The whole reexports of a module. + StarReexports, /// A facade of the module behaving like the original, but referencing /// internal parts. Facade, @@ -2889,7 +2894,11 @@ impl ModulePart { } #[turbo_tasks::function] pub fn export(export: RcStr) -> Vc { - ModulePart::Export(Vc::cell(export)).cell() + ModulePart::Export(Vc::cell(export), Vc::cell(false)).cell() + } + #[turbo_tasks::function] + pub fn proxied_export(export: Vc) -> Vc { + ModulePart::Export(export, Vc::cell(true)).cell() } #[turbo_tasks::function] pub fn renamed_export(original_export: RcStr, export: RcStr) -> Vc { @@ -2919,6 +2928,10 @@ impl ModulePart { ModulePart::Exports.cell() } #[turbo_tasks::function] + pub fn star_reexports() -> Vc { + ModulePart::StarReexports.cell() + } + #[turbo_tasks::function] pub fn facade() -> Vc { ModulePart::Facade.cell() } @@ -2930,7 +2943,7 @@ impl ValueToString for ModulePart { async fn to_string(&self) -> Result> { Ok(Vc::cell(match self { ModulePart::Evaluation => "module evaluation".into(), - ModulePart::Export(export) => format!("export {}", export.await?).into(), + ModulePart::Export(export, _) => format!("export {}", export.await?).into(), ModulePart::RenamedExport { original_export, export, @@ -2945,6 +2958,7 @@ impl ValueToString for ModulePart { ModulePart::Internal(id) => format!("internal part {}", id,).into(), ModulePart::Locals => "locals".into(), ModulePart::Exports => "exports".into(), + ModulePart::StarReexports => "reexports".into(), ModulePart::Facade => "facade".into(), })) } diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs index b98f4b020927f..c914232e5d55b 100644 --- a/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs @@ -200,8 +200,43 @@ pub(crate) enum ImportedSymbol { ModuleEvaluation, Symbol(JsWord), Exports, + /// We need a separate variant for `export * from 'package-star'`. + /// + /// `package-star/index.js`: + /// + /// ``` + /// export { notCompiled } from "./not-compiled.js"; + /// export { notExisting } from "./not-existing.js"; + /// export { notExecuted } from "./not-executed.js"; + /// export * from "./not-executed.js"; + /// export * from "./a.js"; + /// export * from "./b.js"; + /// export const local = "local"; + /// ``` + /// + /// + /// `package-reexport/index.js`: + /// + /// ``` + /// export * from "package-star"; + /// export const outer = "outer"; + /// ``` + /// + /// `import { a } from 'package-reexport'` currently creates `ModulePart::Export("a")` for + /// `package-reexport` and `ModulePart::Exports` for `package-star`. + /// + /// To make side effect optimization work, we need to create `ModulePart::Export("a")`for + /// `export * from "package-star"`. + /// + /// But we cannot make `ImportAnalyzer` or `EvalContext` take the name of the target symbol, + /// because it will make them parameterized by the name of the target symbol and it's too bad + /// for caching. + /// + /// So we need to have a separate variant, and reuse the requested `ModulePart` for reexports. + ReexportAll, Part(u32), PartEvaluation(u32), + StarReexports, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -402,7 +437,7 @@ impl Visit for Analyzer<'_> { let i = self.ensure_reference( export.span, export.src.value.clone(), - symbol.unwrap_or(ImportedSymbol::Exports), + symbol.unwrap_or(ImportedSymbol::ReexportAll), annotations, ); if let Some(i) = i { @@ -586,12 +621,15 @@ pub(crate) fn orig_name(n: &ModuleExportName) -> JsWord { } fn parse_with(with: Option<&ObjectLit>) -> Option { - find_turbopack_part_id_in_asserts(with?).map(|v| match v { + let id = find_turbopack_part_id_in_asserts(with?)?; + + Some(match id { PartId::Internal(index, true) => ImportedSymbol::PartEvaluation(index), PartId::Internal(index, false) => ImportedSymbol::Part(index), PartId::ModuleEvaluation => ImportedSymbol::ModuleEvaluation, PartId::Export(e) => ImportedSymbol::Symbol(e.as_str().into()), PartId::Exports => ImportedSymbol::Exports, + PartId::StarReexports => ImportedSymbol::StarReexports, }) } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 48fec1645f5da..4fe6176361234 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -152,8 +152,8 @@ impl ModuleReference for EsmAssetReference { async fn resolve_reference(&self) -> Result> { let ty = if matches!(self.annotations.module_type(), Some("json")) { EcmaScriptModulesReferenceSubType::ImportWithType(ImportWithType::Json) - } else if let Some(part) = &self.export_name { - EcmaScriptModulesReferenceSubType::ImportPart(*part) + } else if let Some(part) = self.export_name { + EcmaScriptModulesReferenceSubType::ImportPart(part) } else { EcmaScriptModulesReferenceSubType::Import }; @@ -166,10 +166,12 @@ impl ModuleReference for EsmAssetReference { .await? .expect("EsmAssetReference origin should be a EcmascriptModuleAsset"); - return Ok(ModuleResolveResult::module( - EcmascriptModulePartAsset::select_part(module, part), - ) - .cell()); + let part_module = *EcmascriptModulePartAsset::select_part(module, part).await?; + + return match part_module { + Some(part_module) => Ok(ModuleResolveResult::module(part_module).cell()), + None => Ok(ModuleResolveResult::ignored().cell()), + }; } bail!("export_name is required for part import") @@ -186,18 +188,22 @@ impl ModuleReference for EsmAssetReference { if let Some(part) = self.export_name { let part = part.await?; - if let &ModulePart::Export(export_name) = &*part { - for &module in result.primary_modules().await? { - if let Some(module) = Vc::try_resolve_downcast(module).await? { - let export = export_name.await?; - if *is_export_missing(module, export.clone_value()).await? { - InvalidExport { - export: export_name, - module, - source: self.issue_source, + if let &ModulePart::Export(export_name, is_proxy) = &*part { + // If is_proxy true, user did not speicifed the exact export name in the direct + // import. Instead, they did `export * from './foo'`. + if !*is_proxy.await? { + for &module in result.primary_modules().await? { + if let Some(module) = Vc::try_resolve_downcast(module).await? { + let export = export_name.await?; + if *is_export_missing(module, export.clone_value()).await? { + InvalidExport { + export: export_name, + module, + source: self.issue_source, + } + .cell() + .emit(); } - .cell() - .emit(); } } } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index 5a165cd0b578f..f0ff0bc9a7762 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -605,6 +605,19 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), ImportedSymbol::Exports => Some(ModulePart::exports()), + ImportedSymbol::StarReexports => Some(ModulePart::star_reexports()), + ImportedSymbol::ReexportAll => Some(match part { + Some(part) => match &*part.await? { + ModulePart::Evaluation => { + evaluation_references.push(i); + ModulePart::evaluation() + } + + ModulePart::Export(e, ..) => ModulePart::proxied_export(*e), + _ => ModulePart::exports(), + }, + None => ModulePart::exports(), + }), }, Some(TreeShakingMode::ReexportsOnly) => match &r.imported_symbol { ImportedSymbol::ModuleEvaluation => { @@ -615,7 +628,9 @@ pub(crate) async fn analyse_ecmascript_module_internal( ImportedSymbol::PartEvaluation(_) | ImportedSymbol::Part(_) => { bail!("Internal imports doesn't exist in reexports only mode") } - ImportedSymbol::Exports => None, + ImportedSymbol::Exports + | ImportedSymbol::ReexportAll + | ImportedSymbol::StarReexports => None, }, None => { evaluation_references.push(i); diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs index 8dcec1e902f94..73212d3e7f081 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs @@ -104,8 +104,15 @@ impl Module for EcmascriptModuleFacadeModule { self.module, ModulePart::locals(), ))); + references.push(Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::star_reexports(), + ))); references } + ModulePart::StarReexports { .. } => { + vec![] + } ModulePart::Facade => { vec![ Vc::upcast(EcmascriptModulePartReference::new_part( @@ -194,6 +201,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule { } star_exports.extend(esm_exports.star_exports.iter().copied()); } + ModulePart::StarReexports => {} ModulePart::Facade => { // Reexport everything from the reexports module // (including default export if any) @@ -268,6 +276,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule { .module .is_marked_as_side_effect_free(side_effect_free_packages), ModulePart::Exports + | ModulePart::StarReexports | ModulePart::RenamedExport { .. } | ModulePart::RenamedNamespace { .. } => Vc::cell(true), _ => bail!("Unexpected ModulePart for EcmascriptModuleFacadeModule"), diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs index bf18271802ac3..33c202cc192f6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -77,7 +77,8 @@ impl ModuleReference for EcmascriptModulePartReference { | ModulePart::Evaluation | ModulePart::Facade | ModulePart::RenamedExport { .. } - | ModulePart::RenamedNamespace { .. } => { + | ModulePart::RenamedNamespace { .. } + | ModulePart::StarReexports => { Vc::upcast(EcmascriptModuleFacadeModule::new(self.module, part)) } ModulePart::Export(..) | ModulePart::Internal(..) => { diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 59e1cd9f661b0..ac40484d5dea4 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -92,24 +92,34 @@ impl EcmascriptModulePartAsset { .cell() } + /// Returns `None` only if the part is a proxied export. (Which is allowed to not exist) #[turbo_tasks::function] pub async fn select_part( module: Vc, part: Vc, - ) -> Result>> { + ) -> Result> { let split_result = split_module(module).await?; - Ok(if matches!(&*split_result, SplitResult::Failed { .. }) { - Vc::upcast(module) - } else { - Vc::upcast(EcmascriptModulePartAsset::new(module, part)) - }) + Ok(Vc::cell( + if matches!(&*split_result, SplitResult::Failed { .. }) { + Some(Vc::upcast(module)) + } else if matches!(&*part.await?, ModulePart::Export(..)) { + let part_id = get_part_id(&split_result, part).await?; + if part_id.is_some() { + Some(Vc::upcast(EcmascriptModulePartAsset::new(module, part))) + } else { + None + } + } else { + Some(Vc::upcast(EcmascriptModulePartAsset::new(module, part))) + }, + )) } #[turbo_tasks::function] pub async fn is_async_module(self: Vc) -> Result> { let this = self.await?; - let result = this.full_module.analyze(); + let result = analyse_ecmascript_module(this.full_module, Some(this.part)); if let Some(async_module) = *result.await?.async_module.await? { Ok(async_module.is_self_async(self.references())) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs index 9c50b4f10a6b4..dd6743d8f3f3e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs @@ -209,8 +209,6 @@ pub(super) struct SplitModuleResult { /// Dependency between parts. pub part_deps: FxHashMap>, pub modules: Vec, - - pub star_reexports: Vec, } impl DepGraph { @@ -247,7 +245,7 @@ impl DepGraph { data: &FxHashMap, ) -> SplitModuleResult { let groups = self.finalize(data); - let mut exports = FxHashMap::default(); + let mut results = FxHashMap::default(); let mut part_deps = FxHashMap::<_, Vec>::default(); let star_reexports: Vec<_> = data @@ -256,9 +254,15 @@ impl DepGraph { .cloned() .collect(); let mut modules = vec![]; + let mut exports_module = Module::dummy(); exports_module.body.extend(directives.iter().cloned()); + let mut star_reexports_module = Module::dummy(); + star_reexports_module + .body + .extend(directives.iter().cloned()); + if groups.graph_ix.is_empty() { // If there's no dependency, all nodes are in the module evaluaiotn group. modules.push(Module { @@ -266,7 +270,7 @@ impl DepGraph { body: data.values().map(|v| v.content.clone()).collect(), shebang: None, }); - exports.insert(Key::ModuleEvaluation, 0); + results.insert(Key::ModuleEvaluation, 0); } let mut declarator = FxHashMap::default(); @@ -337,7 +341,7 @@ impl DepGraph { ItemId::Group(ItemIdGroupKind::Export(..)) => { if let Some(export) = &data[item].export { use_export_instead_of_declarator = true; - exports.insert(Key::Export(export.as_str().into()), ix as u32); + results.insert(Key::Export(export.as_str().into()), ix as u32); let s = ExportSpecifier::Named(ExportNamedSpecifier { span: DUMMY_SP, @@ -363,7 +367,7 @@ impl DepGraph { } } ItemId::Group(ItemIdGroupKind::ModuleEvaluation) => { - exports.insert(Key::ModuleEvaluation, ix as u32); + results.insert(Key::ModuleEvaluation, ix as u32); } _ => {} @@ -505,18 +509,23 @@ impl DepGraph { } for g in group { + let item = &data[g].content; // Skip directives, as we copy them to each modules. if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr: box Expr::Lit(Lit::Str(s)), .. - })) = &data[g].content + })) = item { if s.value.starts_with("use ") { continue; } } - chunk.body.push(data[g].content.clone()); + if let ModuleItem::ModuleDecl(ModuleDecl::ExportAll(..)) = item { + continue; + } + + chunk.body.push(item.clone()); } for g in group { @@ -562,21 +571,36 @@ impl DepGraph { modules.push(chunk); } - exports.insert(Key::Exports, modules.len() as u32); - - for star in &star_reexports { + if !star_reexports.is_empty() { + // `Exports` module should export everything from the re-exported modules exports_module .body - .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(star.clone()))); + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ExportAll { + span: DUMMY_SP, + src: Box::new(TURBOPACK_PART_IMPORT_SOURCE.into()), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert( + PartId::StarReexports, + ))), + }))); + + for star in &star_reexports { + star_reexports_module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(star.clone()))); + } + + results.insert(Key::StarReexports, modules.len() as u32); + modules.push(star_reexports_module); } + results.insert(Key::Exports, modules.len() as u32); modules.push(exports_module); SplitModuleResult { - entrypoints: exports, + entrypoints: results, part_deps, modules, - star_reexports, } } @@ -911,7 +935,7 @@ impl DepGraph { // One item for the import for re-export let id = ItemId::Item { index, - kind: ItemIdItemKind::ImportOfModule, + kind: ItemIdItemKind::Normal, }; ids.push(id.clone()); items.insert( @@ -1304,6 +1328,7 @@ pub(crate) enum PartId { Export(RcStr), /// `(part_id, is_for_eval)` Internal(u32, bool), + StarReexports, } pub(crate) fn create_turbopack_part_id_assert(dep: PartId) -> ObjectLit { @@ -1325,6 +1350,7 @@ pub(crate) fn create_turbopack_part_id_assert(dep: PartId) -> ObjectLit { } } .into(), + PartId::StarReexports => "reexports".into(), }, })))], } @@ -1346,6 +1372,7 @@ pub(crate) fn find_turbopack_part_id_in_asserts(asserts: &ObjectLit) -> Option

match &*s.value { "module evaluation" => Some(PartId::ModuleEvaluation), "exports" => Some(PartId::Exports), + "reexports" => Some(PartId::StarReexports), _ if s.value.starts_with("export ") => Some(PartId::Export(s.value[7..].into())), _ => None, }, diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs index 27dc800bb18d2..b837c3661e465 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -7,13 +7,13 @@ use swc_core::{ common::{comments::Comments, util::take::Take, SyntaxContext, DUMMY_SP, GLOBALS}, ecma::{ ast::{ - ExportAll, ExportNamedSpecifier, Expr, ExprStmt, Id, Ident, ImportDecl, Lit, Module, - ModuleDecl, ModuleExportName, ModuleItem, NamedExport, Program, Stmt, + ExportNamedSpecifier, Expr, ExprStmt, Id, Ident, ImportDecl, Lit, Module, ModuleDecl, + ModuleExportName, ModuleItem, NamedExport, Program, Stmt, }, codegen::to_code, }, }; -use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks::{debug::ValueDebugFormat, RcStr, ValueToString, Vc}; use turbopack_core::{ident::AssetIdent, resolve::ModulePart, source::Source}; pub(crate) use self::graph::{ @@ -324,23 +324,29 @@ pub(crate) enum Key { ModuleEvaluation, Export(RcStr), Exports, + /// Star-reexports, excluding known exports + StarReexports, } /// Converts [Vc] to the index. -async fn get_part_id(result: &SplitResult, part: Vc) -> Result { - let part = part.await?; +async fn get_part_id(result: &SplitResult, part_vc: Vc) -> Result> { + let part = part_vc.await?; // TODO implement ModulePart::Facade let key = match &*part { ModulePart::Evaluation => Key::ModuleEvaluation, - ModulePart::Export(export) => Key::Export(export.await?.as_str().into()), + ModulePart::Export(export, _) => Key::Export(export.await?.as_str().into()), ModulePart::Exports => Key::Exports, - ModulePart::Internal(part_id) => return Ok(*part_id), + ModulePart::StarReexports => Key::StarReexports, + ModulePart::Internal(part_id) => return Ok(Some(*part_id)), ModulePart::Locals | ModulePart::Facade | ModulePart::RenamedExport { .. } | ModulePart::RenamedNamespace { .. } => { - bail!("invalid module part") + bail!( + "invalid module part: {:?}", + part_vc.value_debug_format(10).try_to_string().await? + ) } }; @@ -353,15 +359,16 @@ async fn get_part_id(result: &SplitResult, part: Vc) -> Result bail!("split failed") }; - if let Some(id) = entrypoints.get(&key) { - return Ok(*id); + if let Some(&id) = entrypoints.get(&key) { + return Ok(Some(id)); } // This is required to handle `export * from 'foo'` if let ModulePart::Export(..) = &*part { - if let Some(&v) = entrypoints.get(&Key::Exports) { - return Ok(v); + if let Some(&v) = entrypoints.get(&Key::StarReexports) { + return Ok(Some(v)); } + return Ok(None); } let mut dump = String::new(); @@ -399,9 +406,6 @@ pub(crate) enum SplitResult { #[turbo_tasks(trace_ignore)] deps: FxHashMap>, - - #[turbo_tasks(debug_ignore, trace_ignore)] - star_reexports: Vec, }, Failed { parse_result: Vc, @@ -507,7 +511,6 @@ pub(super) async fn split( entrypoints, part_deps, modules, - star_reexports, } = dep_graph.split_module(&directives, &items); assert_ne!(modules.len(), 0, "modules.len() == 0;\nModule: {module:?}",); @@ -547,7 +550,6 @@ pub(super) async fn split( entrypoints, deps: part_deps, modules, - star_reexports, } .cell()) } @@ -572,7 +574,6 @@ pub(crate) async fn part_of_module( modules, entrypoints, deps, - star_reexports, .. } => { debug_assert_ne!(modules.len(), 0, "modules.len() == 0"); @@ -643,10 +644,6 @@ pub(crate) async fn part_of_module( }, ))); - module.body.extend(star_reexports.iter().map(|export_all| { - ModuleItem::ModuleDecl(ModuleDecl::ExportAll(export_all.clone())) - })); - let program = Program::Module(module); let eval_context = EvalContext::new( &program, @@ -671,6 +668,10 @@ pub(crate) async fn part_of_module( let part_id = get_part_id(&split_data, part).await?; + let Some(part_id) = part_id else { + bail!("part_id is None"); + }; + if part_id as usize >= modules.len() { bail!( "part_id is out of range: {part_id} >= {}; asset = {}; entrypoints = \ diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs index b9f0ade864b4f..eea6320906a11 100644 --- a/turbopack/crates/turbopack/src/lib.rs +++ b/turbopack/crates/turbopack/src/lib.rs @@ -190,10 +190,15 @@ async fn apply_module_type( let options = options.await?; match options.tree_shaking_mode { Some(TreeShakingMode::ModuleFragments) => { - Vc::upcast(EcmascriptModulePartAsset::select_part( + let part_module = EcmascriptModulePartAsset::select_part( module, part.unwrap_or(ModulePart::facade()), - )) + ); + if let Some(part_module) = *part_module.await? { + Vc::upcast(part_module) + } else { + return Ok(ProcessResult::Ignore.cell()); + } } Some(TreeShakingMode::ReexportsOnly) => { if let Some(part) = part { @@ -208,7 +213,7 @@ async fn apply_module_type( Vc::upcast(module) } } - ModulePart::Export(_) => { + ModulePart::Export(..) => { let side_effect_free_packages = module_asset_context.side_effect_free_packages(); @@ -290,7 +295,7 @@ async fn apply_reexport_tree_shaking( part: Vc, side_effect_free_packages: Vc, ) -> Result>> { - if let ModulePart::Export(export) = *part.await? { + if let ModulePart::Export(export, ..) = *part.await? { let export = export.await?; let FollowExportsResult { module: final_module, From ff6bb0d0c66cfc00f4813b9378cb6b979058db7e 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, 24 Sep 2024 10:29:07 +0900 Subject: [PATCH 03/10] Add a test --- .../tests/tree-shaker/analyzer/barrel-file/input.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/input.js diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/input.js new file mode 100644 index 0000000000000..5edefced6047b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/input.js @@ -0,0 +1,11 @@ +export * from './_1'; +export * from './_2'; +export * from './_3'; +export * from './_4'; +export * from './_5'; + + + +export const a = 1; + +console.log('foo') From 86bc05e07a03fcde3cd88754618dcf7701d25917 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, 24 Sep 2024 10:32:23 +0900 Subject: [PATCH 04/10] Do not panic --- .../crates/turbopack-ecmascript/src/tree_shake/tests.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs index 60cec2fa34bf1..2bb5f4c93e10e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs @@ -218,8 +218,10 @@ fn run(input: PathBuf) { ItemIdGroupKind::Export(_, name) => Key::Export(name.as_str().into()), }; - let index = entrypoints[&key]; - entry.body.extend(modules[index as usize].body.clone()); + let index = entrypoints.get(&key); + if let Some(&index) = index { + entry.body.extend(modules[index as usize].body.clone()); + } } let module = merger.merge_recursively(entry).unwrap(); From 727013a31d4887c5c7d8816a3016909e37099516 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, 24 Sep 2024 10:55:44 +0900 Subject: [PATCH 05/10] `ItemData::skip_content` --- .../src/tree_shake/graph.rs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs index dd6743d8f3f3e..94e4ba7e01f79 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs @@ -113,6 +113,27 @@ pub(crate) struct ItemData { pub export: Option, } +impl ItemData { + pub(super) fn skip_content(&self) -> bool { + // Skip directives, as we copy them to each modules. + if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { + expr: box Expr::Lit(Lit::Str(s)), + .. + })) = &self.content + { + if s.value.starts_with("use ") { + return true; + } + } + + if let ModuleItem::ModuleDecl(ModuleDecl::ExportAll(..)) = &self.content { + return true; + } + + false + } +} + impl fmt::Debug for ItemData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ItemData") @@ -509,23 +530,12 @@ impl DepGraph { } for g in group { - let item = &data[g].content; - // Skip directives, as we copy them to each modules. - if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { - expr: box Expr::Lit(Lit::Str(s)), - .. - })) = item - { - if s.value.starts_with("use ") { - continue; - } - } - - if let ModuleItem::ModuleDecl(ModuleDecl::ExportAll(..)) = item { + let item = &data[g]; + if item.skip_content() { continue; } - chunk.body.push(item.clone()); + chunk.body.push(item.content.clone()); } for g in group { From bd619f9813b82bc993bdbf36c2ff9b0cc2a31e81 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, 24 Sep 2024 10:58:04 +0900 Subject: [PATCH 06/10] Optimize --- .../crates/turbopack-ecmascript/src/tree_shake/graph.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs index 94e4ba7e01f79..c770666da4e3b 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs @@ -632,6 +632,15 @@ impl DepGraph { let mapped = condensed.filter_map( |_, node| { + if node.iter().all(|&ix| { + let id = &self.g.graph_ix[ix as usize]; + + data[id].skip_content() + }) { + done.extend(node.iter().copied()); + return None; + } + let mut item_ids = node .iter() .map(|&ix| { From bb3ba22016049dae153200abfff2ff1e10390858 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, 24 Sep 2024 10:58:31 +0900 Subject: [PATCH 07/10] Update test refs --- .../analyzer/barrel-file/output.md | 355 ++++++++++++++++++ ...-shake_export-named_input_index_270dac.js} | 2 +- ...ke_export-named_input_index_270dac.js.map} | 0 ...ke_export-namespace_input_index_47423a.js} | 2 +- ...xport-namespace_input_index_47423a.js.map} | 0 ...ke_import-named-all_input_index_76740d.js} | 2 +- ...mport-named-all_input_index_76740d.js.map} | 0 ...-shake_import-named_input_index_f1c17b.js} | 2 +- ...ke_import-named_input_index_f1c17b.js.map} | 0 ...ke_import-namespace_input_index_8ea19b.js} | 2 +- ...mport-namespace_input_index_8ea19b.js.map} | 0 ..._import-side-effect_input_index_10f2f7.js} | 2 +- ...ort-side-effect_input_index_10f2f7.js.map} | 0 ...e_tree-shake-test-1_input_index_7237f8.js} | 2 +- ...ee-shake-test-1_input_index_7237f8.js.map} | 0 15 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/output.md rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/{b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js => b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js} (91%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/{b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js.map => b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/{4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js => 4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js} (93%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/{4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js.map => 4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/{4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js => 4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js} (93%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/{4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js.map => 4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/{b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js => b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js} (91%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/{b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js.map => b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/{4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js => 4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js} (93%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/{4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js.map => 4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/{4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js => 4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js} (93%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/{4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js.map => 4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js.map} (100%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/{4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js => 4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js} (93%) rename turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/{4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js.map => 4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js.map} (100%) diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/output.md new file mode 100644 index 0000000000000..065b6151fd681 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/barrel-file/output.md @@ -0,0 +1,355 @@ +# Items + +Count: 9 + +## Item 1: Stmt 0, `Normal` + +```js +export * from './_1'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 1, `Normal` + +```js +export * from './_2'; + +``` + +- Hoisted +- Side effects + +## Item 3: Stmt 2, `Normal` + +```js +export * from './_3'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 3, `Normal` + +```js +export * from './_4'; + +``` + +- Hoisted +- Side effects + +## Item 5: Stmt 4, `Normal` + +```js +export * from './_5'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 5, `VarDeclarator(0)` + +```js +export const a = 1; + +``` + +- Declares: `a` +- Write: `a` + +## Item 7: Stmt 6, `Normal` + +```js +console.log('foo'); + +``` + +- Side effects + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export a"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export a"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item6; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export a"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item6; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export a"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item6; + Item8 --> Item1; + Item8 --> Item2; + Item8 --> Item3; + Item8 --> Item4; + Item8 --> Item5; + Item8 --> Item7; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(5, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("a", #2), "a"))]"]; + N2["Items: [ItemId(6, Normal)]"]; + N3["Items: [ItemId(ModuleEvaluation)]"]; + N1 --> N0; + N3 --> N2; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Exports: 5, + Export( + "a", + ): 1, + StarReexports: 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +const a = 1; +export { a as a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a as a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { a }; + +``` +## Part 2 +```js +console.log('foo'); + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js +export * from './_3'; +export * from './_5'; +export * from './_4'; +export * from './_1'; +export * from './_2'; + +``` +## Part 5 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export * from "__TURBOPACK_PART__" assert { + __turbopack_part__: "reexports" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Exports: 5, + Export( + "a", + ): 1, + StarReexports: 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +const a = 1; +export { a as a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a as a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { a }; + +``` +## Part 2 +```js +console.log('foo'); + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js +export * from './_3'; +export * from './_5'; +export * from './_4'; +export * from './_1'; +export * from './_2'; + +``` +## Part 5 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export * from "__TURBOPACK_PART__" assert { + __turbopack_part__: "reexports" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js similarity index 91% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js index 069bedbfcbf91..657961bcad361 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js", + "output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_1823b4._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_ebcda1.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_index_270dac.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js index ee2470d662702..0db27d4d93a7d 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js", + "output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_6b9ee3._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_6e3058.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/4c35f_tests_snapshot_basic-tree-shake_export-namespace_input_index_47423a.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js index 58da9fcecc774..d2e64a7ba4bce 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js", + "output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_84a6ca._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_54a3dd.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/4c35f_tests_snapshot_basic-tree-shake_import-named-all_input_index_76740d.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js similarity index 91% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js index 723b5e901866d..30cdecc724223 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js", + "output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_4f48a0._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_8f179f.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_index_f1c17b.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js index 0e85ee8edeba4..dd55fa31de875 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js", + "output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_519014._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_87b9b1.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/4c35f_tests_snapshot_basic-tree-shake_import-namespace_input_index_8ea19b.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js index 899db454e6133..28759e4749691 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js", + "output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js", {}, {"otherChunks":["output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_55cb06._.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_054c58.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_import-side-effect_input_index_10f2f7.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js index 3b57f19195cd6..b765b7f61eda7 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js @@ -1,5 +1,5 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ - "output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js", + "output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js", {}, {"otherChunks":["output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_950e23.js"],"runtimeModuleIds":["[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript)"]} ]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js.map similarity index 100% rename from turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_c50310.js.map rename to turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_7237f8.js.map From 5ec9b8ef4fddb902e5f6a68a5118abe1472d3469 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, 24 Sep 2024 11:40:55 +0900 Subject: [PATCH 08/10] Always create star reexports part --- .../turbopack-ecmascript/src/tree_shake/graph.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs index c770666da4e3b..65eb2af0c8e79 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs @@ -593,17 +593,17 @@ impl DepGraph { PartId::StarReexports, ))), }))); + } - for star in &star_reexports { - star_reexports_module - .body - .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(star.clone()))); - } - - results.insert(Key::StarReexports, modules.len() as u32); - modules.push(star_reexports_module); + for star in &star_reexports { + star_reexports_module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(star.clone()))); } + results.insert(Key::StarReexports, modules.len() as u32); + modules.push(star_reexports_module); + results.insert(Key::Exports, modules.len() as u32); modules.push(exports_module); From 6265fe13efcc57f3a6f2704e963865d6c9e7ea2d 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, 24 Sep 2024 12:07:29 +0900 Subject: [PATCH 09/10] Properly use star reexports --- .../side_effect_optimization/facade/module.rs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs index 73212d3e7f081..3f2bfffaed279 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs @@ -111,7 +111,16 @@ impl Module for EcmascriptModuleFacadeModule { references } ModulePart::StarReexports { .. } => { - vec![] + let Some(module) = + Vc::try_resolve_sidecast::>(self.module).await? + else { + bail!( + "Expected EcmascriptModuleAsset for a EcmascriptModuleFacadeModule with \ + ModulePart::Evaluation" + ); + }; + let result = module.analyze().await?; + result.reexport_references.await?.clone_value() } ModulePart::Facade => { vec![ @@ -201,7 +210,16 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule { } star_exports.extend(esm_exports.star_exports.iter().copied()); } - ModulePart::StarReexports => {} + ModulePart::StarReexports => { + let EcmascriptExports::EsmExports(esm_exports) = *self.module.get_exports().await? + else { + bail!( + "EcmascriptModuleFacadeModule must only be used on modules with EsmExports" + ); + }; + let esm_exports = esm_exports.await?; + star_exports.extend(esm_exports.star_exports.iter().copied()); + } ModulePart::Facade => { // Reexport everything from the reexports module // (including default export if any) From 7b1982afba80d633dde91c3caff7b59bf1e5cbb9 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, 8 Oct 2024 13:04:36 +0900 Subject: [PATCH 10/10] Remove `is_proxy` --- turbopack/crates/turbopack-core/src/ident.rs | 3 +-- .../crates/turbopack-core/src/resolve/mod.rs | 13 +++------- .../src/references/esm/base.rs | 26 ++++++++----------- .../src/references/mod.rs | 13 +--------- .../src/tree_shake/asset.rs | 9 ++++--- .../src/tree_shake/mod.rs | 2 +- 6 files changed, 23 insertions(+), 43 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/ident.rs b/turbopack/crates/turbopack-core/src/ident.rs index fcb64a728e2ae..046eb55a68725 100644 --- a/turbopack/crates/turbopack-core/src/ident.rs +++ b/turbopack/crates/turbopack-core/src/ident.rs @@ -261,10 +261,9 @@ impl AssetIdent { ModulePart::Evaluation => { 1_u8.deterministic_hash(&mut hasher); } - ModulePart::Export(export, is_proxy) => { + ModulePart::Export(export) => { 2_u8.deterministic_hash(&mut hasher); export.await?.deterministic_hash(&mut hasher); - is_proxy.await?.deterministic_hash(&mut hasher); } ModulePart::RenamedExport { original_export, diff --git a/turbopack/crates/turbopack-core/src/resolve/mod.rs b/turbopack/crates/turbopack-core/src/resolve/mod.rs index b8481d16f3c58..2c5fcbd05f107 100644 --- a/turbopack/crates/turbopack-core/src/resolve/mod.rs +++ b/turbopack/crates/turbopack-core/src/resolve/mod.rs @@ -2862,10 +2862,7 @@ pub enum ModulePart { /// all exports are unused. Evaluation, /// Represents an export of a module. - /// - /// - /// bool value is true if it's proxied for `export * from './foo'` - Export(Vc, Vc), + Export(Vc), /// Represents a renamed export of a module. RenamedExport { original_export: Vc, @@ -2894,11 +2891,7 @@ impl ModulePart { } #[turbo_tasks::function] pub fn export(export: RcStr) -> Vc { - ModulePart::Export(Vc::cell(export), Vc::cell(false)).cell() - } - #[turbo_tasks::function] - pub fn proxied_export(export: Vc) -> Vc { - ModulePart::Export(export, Vc::cell(true)).cell() + ModulePart::Export(Vc::cell(export)).cell() } #[turbo_tasks::function] pub fn renamed_export(original_export: RcStr, export: RcStr) -> Vc { @@ -2943,7 +2936,7 @@ impl ValueToString for ModulePart { async fn to_string(&self) -> Result> { Ok(Vc::cell(match self { ModulePart::Evaluation => "module evaluation".into(), - ModulePart::Export(export, _) => format!("export {}", export.await?).into(), + ModulePart::Export(export) => format!("export {}", export.await?).into(), ModulePart::RenamedExport { original_export, export, diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 4fe6176361234..ad01f5329138f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -188,22 +188,18 @@ impl ModuleReference for EsmAssetReference { if let Some(part) = self.export_name { let part = part.await?; - if let &ModulePart::Export(export_name, is_proxy) = &*part { - // If is_proxy true, user did not speicifed the exact export name in the direct - // import. Instead, they did `export * from './foo'`. - if !*is_proxy.await? { - for &module in result.primary_modules().await? { - if let Some(module) = Vc::try_resolve_downcast(module).await? { - let export = export_name.await?; - if *is_export_missing(module, export.clone_value()).await? { - InvalidExport { - export: export_name, - module, - source: self.issue_source, - } - .cell() - .emit(); + if let &ModulePart::Export(export_name) = &*part { + for &module in result.primary_modules().await? { + if let Some(module) = Vc::try_resolve_downcast(module).await? { + let export = export_name.await?; + if *is_export_missing(module, export.clone_value()).await? { + InvalidExport { + export: export_name, + module, + source: self.issue_source, } + .cell() + .emit(); } } } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index f0ff0bc9a7762..9be435309f421 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -606,18 +606,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), ImportedSymbol::Exports => Some(ModulePart::exports()), ImportedSymbol::StarReexports => Some(ModulePart::star_reexports()), - ImportedSymbol::ReexportAll => Some(match part { - Some(part) => match &*part.await? { - ModulePart::Evaluation => { - evaluation_references.push(i); - ModulePart::evaluation() - } - - ModulePart::Export(e, ..) => ModulePart::proxied_export(*e), - _ => ModulePart::exports(), - }, - None => ModulePart::exports(), - }), + ImportedSymbol::ReexportAll => Some(ModulePart::exports()), }, Some(TreeShakingMode::ReexportsOnly) => match &r.imported_symbol { ImportedSymbol::ModuleEvaluation => { diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs index ac40484d5dea4..001d2e63aa0da 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -4,7 +4,7 @@ use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{AsyncModuleInfo, ChunkableModule, ChunkingContext, EvaluatableAsset}, ident::AssetIdent, - module::Module, + module::{Module, OptionModule}, reference::{ModuleReference, ModuleReferences, SingleModuleReference}, resolve::ModulePart, }; @@ -170,9 +170,12 @@ impl Module for EcmascriptModulePartAsset { } let deps = { - let part_id = get_part_id(&split_data, self.part) + let Some(part_id) = get_part_id(&split_data, self.part) .await - .with_context(|| format!("part {:?} is not found in the module", self.part))?; + .with_context(|| format!("part {:?} is not found in the module", self.part))? + else { + return Ok(analyze.references); + }; match deps.get(&part_id) { Some(v) => &**v, diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs index b837c3661e465..43c9c251d1456 100644 --- a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -335,7 +335,7 @@ async fn get_part_id(result: &SplitResult, part_vc: Vc) -> Result Key::ModuleEvaluation, - ModulePart::Export(export, _) => Key::Export(export.await?.as_str().into()), + ModulePart::Export(export) => Key::Export(export.await?.as_str().into()), ModulePart::Exports => Key::Exports, ModulePart::StarReexports => Key::StarReexports, ModulePart::Internal(part_id) => return Ok(Some(*part_id)),