From feae24f95b87221bd72e2390a2b686935bf1c5eb Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 17:27:15 +0200 Subject: [PATCH 01/59] Always set exports on reference --- turbopack/crates/turbopack-ecmascript/src/references/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index 07da584617782..a1c89c06ddf4f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -760,7 +760,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), ImportedSymbol::Exports => Some(ModulePart::exports()), }, - Some(TreeShakingMode::ReexportsOnly) => match &r.imported_symbol { + _ => match &r.imported_symbol { ImportedSymbol::ModuleEvaluation => { should_add_evaluation = true; Some(ModulePart::evaluation()) @@ -776,10 +776,6 @@ pub(crate) async fn analyse_ecmascript_module_internal( } ImportedSymbol::Exports => None, }, - None => { - should_add_evaluation = true; - None - } }, import_externals, ) From d079a8d3618f82cbe26771e49a52f23829c66950 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 5 May 2025 14:24:51 +0200 Subject: [PATCH 02/59] __turbopack_esm_other__ --- .../js/src/browser/runtime/base/build-base.ts | 1 + .../js/src/browser/runtime/base/dev-base.ts | 1 + .../js/src/nodejs/runtime.ts | 1 + .../js/src/shared/runtime-types.d.ts | 5 ++++ .../js/src/shared/runtime-utils.ts | 25 +++++++++++++++++++ .../src/runtime_functions.rs | 5 +++- 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts index ea58f1ad1057a..2c91aace2b843 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts @@ -110,6 +110,7 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { f: moduleContext, i: esmImport.bind(null, module), s: esmExport.bind(null, module, module.exports), + o: esmExportOther.bind(null, moduleCache), j: dynamicExport.bind(null, module, module.exports), v: exportValue.bind(null, module), n: exportNamespace.bind(null, module), diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts index 30e8286f3e774..33c2006974225 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts @@ -206,6 +206,7 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { f: moduleContext, i: esmImport.bind(null, module), s: esmExport.bind(null, module, module.exports), + o: esmExportOther.bind(null, devModuleCache), j: dynamicExport.bind(null, module, module.exports), v: exportValue.bind(null, module), n: exportNamespace.bind(null, module), diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts index f5fce590667e9..55c69ab8c608c 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -271,6 +271,7 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { f: moduleContext, i: esmImport.bind(null, module), s: esmExport.bind(null, module, module.exports), + o: esmExportOther.bind(null, moduleCache), j: dynamicExport.bind(null, module, module.exports), v: exportValue.bind(null, module), n: exportNamespace.bind(null, module), diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts index 7fd3eb52a4148..498b1192b1619 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts @@ -37,6 +37,10 @@ type EsmImport = ( allowExportDefault: boolean ) => EsmNamespaceObject | Promise type EsmExport = (exportGetters: Record any>) => void +type EsmExportOther = ( + id: ModuleId, + exportGetters: Record any> +) => void type ExportValue = (value: any) => void type ExportNamespace = (namespace: any) => void type DynamicExport = (object: Record) => void @@ -97,6 +101,7 @@ interface TurbopackBaseContext { f: ModuleContextFactory i: EsmImport s: EsmExport + o: EsmExportOther j: DynamicExport v: ExportValue n: ExportNamespace diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts index 6100e84547a18..413eb72890158 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts @@ -128,6 +128,31 @@ function ensureDynamicExports(module: Module, exports: Exports) { } } +/** + * Makes the specified module an ESM with exports + */ +function esmExportOther( + moduleCache: ModuleCache, + id: ModuleId, + getters: Record any> +) { + let module = moduleCache[id] + if (!module) { + // This is invoked when a module is merged into another module, thus it wasn't invoced via + // instantiateModule and the cache entry wasn't created yet. + module = { + exports: {}, + error: undefined, + loaded: false, + id, + namespaceObject: undefined, + } + moduleCache[id] = module + } + module.namespaceObject = module.exports + esm(module.exports, getters) +} + /** * Dynamically exports properties from an object */ diff --git a/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs b/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs index d09aa3ec61f2f..aa12c7c8d78ff 100644 --- a/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs +++ b/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs @@ -44,6 +44,8 @@ pub const TURBOPACK_IMPORT: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.i", "i"); pub const TURBOPACK_ESM: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.s", "s"); +pub const TURBOPACK_ESM_OTHER: &TurbopackRuntimeFunctionShortcut = + &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.o", "o"); pub const TURBOPACK_EXPORT_VALUE: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.v", "v"); pub const TURBOPACK_EXPORT_NAMESPACE: &TurbopackRuntimeFunctionShortcut = @@ -81,11 +83,12 @@ pub const TURBOPACK_REQUIRE_REAL: &TurbopackRuntimeFunctionShortcut = /// Adding an entry to this list will automatically ensure that `__turbopack_XXX__` can be called /// from user code (by inserting a replacement into free_var_references) -pub const TUBROPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 21] = [ +pub const TUBROPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 22] = [ ("__turbopack_require__", TURBOPACK_REQUIRE), ("__turbopack_module_context__", TURBOPACK_MODULE_CONTEXT), ("__turbopack_import__", TURBOPACK_IMPORT), ("__turbopack_esm__", TURBOPACK_ESM), + ("__turbopack_esm_other__", TURBOPACK_ESM_OTHER), ("__turbopack_export_value__", TURBOPACK_EXPORT_VALUE), ("__turbopack_export_namespace__", TURBOPACK_EXPORT_NAMESPACE), ("__turbopack_cache__", TURBOPACK_CACHE), From 4c9c1242c109da8fd8ebe8b45f5d6f62c8f7184a Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 9 May 2025 12:00:56 +0200 Subject: [PATCH 03/59] Support additional ids in runtime --- .../js/src/browser/runtime/base/dev-base.ts | 2 +- .../src/browser/runtime/base/runtime-base.ts | 12 +++++++-- .../js/src/nodejs/runtime.ts | 26 +++++++++++++++---- .../js/src/shared/runtime-types.d.ts | 9 ++++++- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts index 33c2006974225..91359d2ff241a 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts @@ -43,7 +43,7 @@ interface TurbopackDevContext extends TurbopackDevBaseContext {} type ModuleFactory = ( this: Module['exports'], context: TurbopackDevBaseContext -) => undefined +) => unknown interface DevRuntimeBackend { reloadChunk?: (chunkUrl: ChunkUrl) => Promise diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/runtime-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/runtime-base.ts index 43e1d2bb426ca..4dada0e519f20 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/runtime-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/runtime-base.ts @@ -31,7 +31,7 @@ type RuntimeParams = { type ChunkRegistration = [ chunkPath: ChunkScript, - chunkModules: ModuleFactories, + chunkModules: CompressedModuleFactories, params: RuntimeParams | undefined, ] @@ -361,7 +361,15 @@ function registerChunk([ const chunkPath = getPathFromScript(chunkScript) for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory + moduleFactories[moduleId] = moduleFactoryFn + for (const otherModuleId of otherIds) { + moduleFactories[otherModuleId] = moduleFactoryFn + } + } else { + moduleFactories[moduleId] = moduleFactory + } } addModuleToChunk(moduleId, chunkPath) } diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts index 55c69ab8c608c..4ab0206c8f503 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -56,7 +56,7 @@ interface TurbopackNodeBuildContext extends TurbopackBaseContext { type ModuleFactory = ( this: Module['exports'], context: TurbopackNodeBuildContext -) => undefined +) => unknown const url = require('url') as typeof import('url') const fs = require('fs/promises') as typeof import('fs/promises') @@ -107,11 +107,19 @@ function loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void { try { const resolved = path.resolve(RUNTIME_ROOT, chunkPath) - const chunkModules: ModuleFactories = require(resolved) + const chunkModules: CompressedModuleFactories = require(resolved) for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory + moduleFactories[moduleId] = moduleFactoryFn + for (const otherModuleId of otherIds) { + moduleFactories[otherModuleId] = moduleFactoryFn + } + } else { + moduleFactories[moduleId] = moduleFactory + } } } loadedChunks.add(chunkPath) @@ -165,10 +173,18 @@ async function loadChunkAsync( url.pathToFileURL(resolved) )(module, module.exports, localRequire, path.dirname(resolved), resolved) - const chunkModules: ModuleFactories = module.exports + const chunkModules: CompressedModuleFactories = module.exports for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory + moduleFactories[moduleId] = moduleFactoryFn + for (const otherModuleId of otherIds) { + moduleFactories[otherModuleId] = moduleFactoryFn + } + } else { + moduleFactories[moduleId] = moduleFactory + } } } loadedChunks.add(chunkPath) diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts index 498b1192b1619..3f555f338bd67 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts @@ -13,6 +13,7 @@ type ChunkListScript = CurrentScript & { readonly brand: unique symbol } type ChunkPath = string & { readonly brand: unique symbol } type ChunkScript = CurrentScript & { readonly brand: unique symbol } type ChunkUrl = string & { readonly brand: unique symbol } +// TODO this should actually be `string | number` type ModuleId = string interface Exports { @@ -58,7 +59,13 @@ type LoadWebAssemblyModule = ( ) => WebAssembly.Module type ModuleCache = Record -type ModuleFactories = Record +// TODO properly type values here +type ModuleFactories = Record +// The value is an array with scope hoisting +type CompressedModuleFactories = Record< + ModuleId, + Function | [Function, ModuleId[]] +> type RelativeURL = (inputUrl: string) => void type ResolvePathFromModule = (moduleId: string) => string From c66ccfb6d1ce3d0005a8345a2d25db7b1605a1bf Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 8 May 2025 11:52:02 +0200 Subject: [PATCH 04/59] MergeableModule --- .../crates/turbopack-core/src/chunk/mod.rs | 32 ++++++++++ .../crates/turbopack-ecmascript/src/lib.rs | 59 ++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index b8fed85d52d38..4b9d312940103 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -107,6 +107,38 @@ impl ChunkableModules { } } +#[turbo_tasks::value(shared)] +pub enum MergeableModuleResult { + Merged { + merged_module: ResolvedVc>, + consumed: u32, + skipped: u32, + }, + NotMerged, +} +#[turbo_tasks::value_impl] +impl MergeableModuleResult { + #[turbo_tasks::function] + pub fn not_merged() -> Vc { + MergeableModuleResult::NotMerged.cell() + } +} + +#[turbo_tasks::value_trait] +pub trait MergeableModule: Module + Asset { + fn merge(self: Vc, modules: Vc) -> Vc; +} +#[turbo_tasks::value(transparent)] +pub struct MergeableModules(Vec>>); + +#[turbo_tasks::value_impl] +impl MergeableModules { + #[turbo_tasks::function] + pub fn interned(modules: Vec>>) -> Vc { + Vc::cell(modules) + } +} + #[turbo_tasks::value(transparent)] pub struct Chunks(Vec>>); diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index b7d94e4ea4487..0e30add796a08 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -79,7 +79,7 @@ use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, - MinifyType, + MergeableModule, MergeableModuleResult, MergeableModules, MinifyType, }, compile_time_info::CompileTimeInfo, context::AssetContext, @@ -698,6 +698,63 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleAsset { } } +#[turbo_tasks::value_impl] +impl MergeableModule for EcmascriptModuleAsset { + // Clippy is wrong here, they are not equivalent (the for-loop restarts the iterator) + #[allow(clippy::while_let_on_iterator)] + #[turbo_tasks::function] + async fn merge( + self: ResolvedVc, + modules: Vc, + ) -> Result> { + let modules = modules.await?; + let mut modules = modules.iter(); + + let mut skipped = 0; + let mut consumed_modules = vec![]; + + while let Some(m) = modules.next() { + // Skip some modules, try to find the first eligible module + if let Some(m) = ResolvedVc::try_sidecast::>(*m) { + consumed_modules.push(m); + // Consume as many as possible to merge together + while let Some(m) = modules.next() { + if let Some(m) = ResolvedVc::try_sidecast::>(*m) { + consumed_modules.push(m); + } else { + break; + } + } + if consumed_modules.len() > 1 { + // Successfully found something to + break; + } else { + // Only a single module, ignore this one and try to find a bigger sequence in + // the remaining list. + consumed_modules.clear(); + skipped += 1; + } + } else { + skipped += 1; + } + } + + if !consumed_modules.is_empty() { + #[allow(unreachable_code)] + Ok(MergeableModuleResult::Merged { + consumed: consumed_modules.len() as u32, + skipped, + merged_module: todo!(), + // TODO + // merged_module: MergedEcmascriptModule::new(consumed_modules) + } + .cell()) + } else { + Ok(MergeableModuleResult::not_merged()) + } + } +} + #[turbo_tasks::value_impl] impl EvaluatableAsset for EcmascriptModuleAsset {} From dff9879e2b19ecb348a04855d7990d2a0e43dfb0 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 29 Apr 2025 21:26:58 +0200 Subject: [PATCH 05/59] MergedModules Graph visitor --- .../src/module_graph/merged_modules.rs | 127 ++++++++++++++++++ .../turbopack-core/src/module_graph/mod.rs | 7 + 2 files changed, 134 insertions(+) create mode 100644 turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs new file mode 100644 index 0000000000000..a8206121468d4 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -0,0 +1,127 @@ +use anyhow::Result; +use rustc_hash::{FxHashMap, FxHashSet}; +use turbo_tasks::{FxIndexMap, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc}; + +use crate::{ + module::Module, + module_graph::{GraphTraversalAction, ModuleGraph}, +}; + +#[turbo_tasks::value(transparent)] +pub struct MergedModules(SliceMap>, bool>); +#[turbo_tasks::value_impl] +impl MergedModules { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(Default::default()) + } +} + +// TODO maybe a smallvec once we know the size distribution? +#[turbo_tasks::value] +pub struct MergedModuleInfo { + groups: FxHashMap>, ResolvedVc>, + included: FxHashSet>>, +} + +#[turbo_tasks::value_impl] +impl MergedModuleInfo { + #[turbo_tasks::function] + pub fn additional_modules_for_entry( + &self, + module: ResolvedVc>, + ) -> Vc { + self.groups + .get(&module) + .map(|v| **v) + .unwrap_or_else(MergedModules::empty) + } + + #[turbo_tasks::function] + pub fn should_create_chunk_item_for(&self, module: ResolvedVc>) -> Vc { + Vc::cell(!self.included.contains(&module)) + } +} + +pub async fn compute_merged_modules(module_graph: Vc) -> Result> { + let chunk_groups = module_graph.chunk_group_info().await?; + let module_graph = module_graph.await?; + + #[allow(clippy::type_complexity)] + let mut groups: FxIndexMap< + ResolvedVc>, + FxIndexMap>, bool>, + > = Default::default(); + let mut included: FxHashSet>> = FxHashSet::default(); + + // let parents = FxHashMap::default(); + + for chunk_group in &chunk_groups.chunk_groups { + // struct State { + // first: Option>>, + // } + // let mut state = State { first: None }; + let entries = FxHashSet::from_iter(chunk_group.entries()); + let mut first = None; + module_graph + .traverse_edges_from_entries_topological( + chunk_group.entries(), + &mut (), + |parent_info, _node, _| { + if parent_info.is_none_or(|p| p.1.is_parallel()) { + Ok(GraphTraversalAction::Continue) + } else { + Ok(GraphTraversalAction::Exclude) + } + }, + |_parent_info, node, _| { + let module = node.module; + let is_exposed = entries.contains(&module); + if is_exposed { + groups.entry(module).or_default(); + } else if let Some(first) = first { + if module != first { + included.insert(module); + groups.entry(first).or_default().insert(module, true); + } + } else { + first = Some(module); + groups.entry(module).or_default(); + } + }, + ) + .await?; + } + + println!( + "included {:#?}", + included + .iter() + .map(|m| m.ident().to_string()) + .try_join() + .await? + ); + println!( + "groups {:#?}", + groups + .iter() + .map(async |(k, v)| Ok(( + k.ident().to_string().await?, + v.iter() + .map(async |(m, exposed)| Ok((m.ident().to_string().await?, exposed))) + .try_join() + .await? + ))) + .try_join() + .await? + ); + + Ok(MergedModuleInfo { + groups: groups + .into_iter() + .map(|(k, v)| (k, ResolvedVc::cell(v.into_iter().collect()))) + .collect(), + included, + } + .cell()) +} diff --git a/turbopack/crates/turbopack-core/src/module_graph/mod.rs b/turbopack/crates/turbopack-core/src/module_graph/mod.rs index 8d2658621e6ff..4c80eab459064 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/mod.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/mod.rs @@ -27,6 +27,7 @@ use crate::{ module_graph::{ async_module_info::{AsyncModulesInfo, compute_async_module_info}, chunk_group_info::{ChunkGroupEntry, ChunkGroupInfo, compute_chunk_group_info}, + merged_modules::{MergedModuleInfo, compute_merged_modules}, module_batches::{ModuleBatchesGraph, compute_module_batches}, style_groups::{StyleGroups, StyleGroupsConfig, compute_style_groups}, traced_di_graph::{TracedDiGraph, iter_neighbors_rev}, @@ -37,6 +38,7 @@ use crate::{ pub mod async_module_info; pub mod chunk_group_info; +pub mod merged_modules; pub mod module_batch; pub(crate) mod module_batches; pub(crate) mod style_groups; @@ -758,6 +760,11 @@ impl ModuleGraph { compute_chunk_group_info(self).await } + #[turbo_tasks::function] + pub async fn merged_modules(self: Vc) -> Result> { + compute_merged_modules(self).await + } + #[turbo_tasks::function] pub async fn module_batches( self: Vc, From c589085bd88053a112c64411760c7a4f8b9881aa Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 8 May 2025 14:35:17 +0200 Subject: [PATCH 06/59] MergedModules Graph visitor --- .../src/module_graph/merged_modules.rs | 251 ++++++++++++++---- 1 file changed, 198 insertions(+), 53 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index a8206121468d4..7551fbb83be6b 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -1,8 +1,13 @@ +use std::cmp::Ordering; + use anyhow::Result; use rustc_hash::{FxHashMap, FxHashSet}; -use turbo_tasks::{FxIndexMap, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc}; +use turbo_tasks::{FxIndexSet, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc}; use crate::{ + chunk::{ + ChunkableModule, ChunkingType, MergeableModule, MergeableModuleResult, MergeableModules, + }, module::Module, module_graph::{GraphTraversalAction, ModuleGraph}, }; @@ -20,79 +25,228 @@ impl MergedModules { // TODO maybe a smallvec once we know the size distribution? #[turbo_tasks::value] pub struct MergedModuleInfo { - groups: FxHashMap>, ResolvedVc>, - included: FxHashSet>>, + /// A map of modules to the merged module containing the module plus additional modules. + #[allow(clippy::type_complexity)] + pub replacements: FxHashMap>, ResolvedVc>>, + /// A map of modules that are already contained as values in replacements. + pub included: FxHashSet>>, } -#[turbo_tasks::value_impl] impl MergedModuleInfo { - #[turbo_tasks::function] - pub fn additional_modules_for_entry( + pub fn should_replace_module( &self, module: ResolvedVc>, - ) -> Vc { - self.groups - .get(&module) - .map(|v| **v) - .unwrap_or_else(MergedModules::empty) + ) -> Option>> { + self.replacements.get(&module).copied() } - #[turbo_tasks::function] - pub fn should_create_chunk_item_for(&self, module: ResolvedVc>) -> Vc { - Vc::cell(!self.included.contains(&module)) + pub fn should_create_chunk_item_for(&self, module: ResolvedVc>) -> bool { + !self.included.contains(&module) } } +/// Determine which modules can be merged together: +/// - if all chunks execute a sequence of modules in the same order, they can be merged together and +/// treated as one. +/// - if a merged module has an incoming edge not contained in the group, it has to expose its +/// exports into the module cache. pub async fn compute_merged_modules(module_graph: Vc) -> Result> { let chunk_groups = module_graph.chunk_group_info().await?; let module_graph = module_graph.await?; #[allow(clippy::type_complexity)] - let mut groups: FxIndexMap< + let mut replacements: FxHashMap< ResolvedVc>, - FxIndexMap>, bool>, + ResolvedVc>, > = Default::default(); let mut included: FxHashSet>> = FxHashSet::default(); - // let parents = FxHashMap::default(); + #[derive(Debug, PartialEq, Eq, Hash)] + struct ListOccurence { + list: usize, + entry: usize, + } + impl PartialOrd for ListOccurence { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + impl Ord for ListOccurence { + fn cmp(&self, other: &Self) -> Ordering { + self.entry.cmp(&other.entry) + } + } + + // A list of all different execution traces (orders) of all modules, initially one for each ESM + // subtree in the chunks, but futher split up later on. + let mut lists: Vec>>> = vec![]; + let mut lists_reverse_map: FxHashMap>, Vec> = + Default::default(); + // Iterate over all chunk groups and collect all potentially mergeable modules (i.e. subtrees + // that are eligible for merging). for chunk_group in &chunk_groups.chunk_groups { - // struct State { - // first: Option>>, - // } - // let mut state = State { first: None }; - let entries = FxHashSet::from_iter(chunk_group.entries()); - let mut first = None; + // TODO parallelize the chunk_group loop + struct State { + lists: Vec>>>, + /// For each module, the lists it is imported into (may be multiple). + current_list_indices: FxHashMap>, usize>, + } + let mut state = State { + lists: vec![], + current_list_indices: FxHashMap::default(), + }; module_graph .traverse_edges_from_entries_topological( chunk_group.entries(), - &mut (), - |parent_info, _node, _| { - if parent_info.is_none_or(|p| p.1.is_parallel()) { - Ok(GraphTraversalAction::Continue) - } else { - Ok(GraphTraversalAction::Exclude) + &mut state, + |parent_info, node, state| { + // On the down traversal, establish which edges are mergable and set the list + // indices. + if parent_info.is_some_and(|p| !p.1.is_parallel()) { + return Ok(GraphTraversalAction::Exclude); + } + let (parent_module, hoisted) = + parent_info.map_or((None, false), |(node, ty)| { + ( + Some(node.module), + match ty { + ChunkingType::Parallel { hoisted, .. } => *hoisted, + _ => unreachable!(), + }, + ) + }); + let module = node.module; + + if ResolvedVc::try_downcast::>(module).is_some() { + let idx = if hoisted + && parent_module.is_some_and(|p| { + ResolvedVc::try_downcast::>(p).is_some() + }) { + // An eligible edge: MergeableModule ---hoisted---> MergeableModule + // Reuse the parent's list to later add the child to it + parent_module + .and_then(|p| state.current_list_indices.get(&p).copied()) + .unwrap_or_else(|| { + let idx = state.lists.len(); + state.lists.push(Default::default()); + idx + }) + } else { + // The module get its own list + let idx = state.lists.len(); + state.lists.push(Default::default()); + idx + }; + state.current_list_indices.insert(module, idx); } + Ok(GraphTraversalAction::Continue) }, - |_parent_info, node, _| { + |_parent_info, node, state| { + // On the up traversal (which corresponds to execution order), add the module to + // the lists it belongs to. let module = node.module; - let is_exposed = entries.contains(&module); - if is_exposed { - groups.entry(module).or_default(); - } else if let Some(first) = first { - if module != first { - included.insert(module); - groups.entry(first).or_default().insert(module, true); + // TODO when is a module exposed? + // let is_exposed = parent_info.is_none(); + + if let Some(mergable_module) = + ResolvedVc::try_downcast::>(module) + { + let idx = *state.current_list_indices.get(&module).unwrap(); + let list = state.lists.get_mut(idx).unwrap(); + + // We might visit the module multiple times, but only add it the first time + // (which corresponds to when it executes). + if list.insert(mergable_module) { + lists_reverse_map.entry(mergable_module).or_default().push( + ListOccurence { + list: idx, + entry: list.len(), + }, + ); } - } else { - first = Some(module); - groups.entry(module).or_default(); } }, ) .await?; + + lists.extend(state.lists); + } + + // Sort the reverse mappings by the index in the lists, so that we start with smaller indices to + // find larger common sequences + for list in lists_reverse_map.values_mut() { + list.sort_unstable(); } + // Split up lists to ensure each module only appears once in a list. + // TODO + + // Call MergeableModule impl to merge the modules (or not, if they are rejected). + let result = lists + .into_iter() + .map(async |list| { + let mut resulting_list = vec![]; + let mut included: Vec>> = vec![]; + + let mut i = 0; + while i < list.len() - 1 { + let first = *list.iter().nth(i).unwrap(); + let modules = list.iter().skip(i).map(|m| **m).collect::>(); + match *first.merge(MergeableModules::interned(modules)).await? { + MergeableModuleResult::Merged { + merged_module, + consumed, + skipped, + } => { + resulting_list + .push((ResolvedVc::upcast::>(first), merged_module)); + included.extend( + list.iter() + .skip(i) + .skip(skipped as usize) + // The first module should not be `included` but `replaced` + .skip(1) + .take(consumed as usize) + .copied() + .map(ResolvedVc::upcast), + ); + i += (skipped + consumed) as usize; + } + MergeableModuleResult::NotMerged => { + // None of them are mergeable. + return Ok(None); + } + } + } + + Ok(Some((resulting_list, included))) + }) + .try_join() + .await?; + + for (replacements_part, included_part) in result.into_iter().flatten() { + replacements.extend(replacements_part.into_iter()); + included.extend(included_part); + } + + // println!( + // "lists {:#?}", + // lists + // .iter() + // .map(|m| m.iter().map(|m| m.ident().to_string()).try_join()) + // .try_join() + // .await? + // ); + // println!( + // "lists_reverse_map {:#?}", + // lists_reverse_map + // .iter() + // .map(async |(k, v)| Ok((k.ident().to_string().await?, v))) + // .try_join() + // .await? + // ); + println!( "included {:#?}", included @@ -102,25 +256,16 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result Date: Fri, 9 May 2025 10:48:26 +0200 Subject: [PATCH 07/59] Convert modules in chunk_group_content --- .../turbopack-core/src/chunk/chunk_group.rs | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs index 8e62c12f2e4c5..e6b37c8de5af5 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs @@ -1,8 +1,8 @@ -use std::collections::HashSet; +use std::{collections::HashSet, sync::atomic::AtomicBool}; use anyhow::{Context, Result}; use rustc_hash::FxHashMap; -use turbo_tasks::{FxIndexSet, ResolvedVc, TryJoinIterExt, Value, Vc}; +use turbo_tasks::{FxIndexSet, ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, Value, Vc}; use super::{ Chunk, ChunkGroupContent, ChunkItem, ChunkItemWithAsyncModuleInfo, ChunkingContext, @@ -192,6 +192,7 @@ pub async fn chunk_group_content( batching_config: Vc, ) -> Result { let module_batches_graph = module_graph.module_batches(batching_config).await?; + let merged_modules = module_graph.merged_modules().await?; type ModuleToChunkableMap = FxHashMap; @@ -315,6 +316,63 @@ pub async fn chunk_group_content( }, )?; + state.chunkable_items = state + .chunkable_items + .into_iter() + .map(async |chunkable_module| match chunkable_module { + ChunkableModuleOrBatch::Module(module) => { + if !merged_modules.should_create_chunk_item_for(ResolvedVc::upcast(module)) { + return Ok(vec![]); + } + + Ok(vec![ChunkableModuleOrBatch::Module( + merged_modules + .should_replace_module(ResolvedVc::upcast(module)) + .unwrap_or(module), + )]) + } + ChunkableModuleOrBatch::Batch(batch) => { + let batch_ref = batch.await?; + let modules = &batch_ref.modules; + + let modified = AtomicBool::new(false); + let modules = modules + .iter() + .filter(|module| { + if merged_modules.should_create_chunk_item_for(ResolvedVc::upcast(**module)) + { + true + } else { + modified.store(true, std::sync::atomic::Ordering::Release); + false + } + }) + .map(|&module| { + if let Some(module) = + merged_modules.should_replace_module(ResolvedVc::upcast(module)) + { + modified.store(true, std::sync::atomic::Ordering::Release); + module + } else { + module + } + }) + .map(ChunkableModuleOrBatch::Module) + .collect::>(); + + if modified.load(std::sync::atomic::Ordering::Acquire) { + Ok(modules) + } else { + Ok(vec![ChunkableModuleOrBatch::Batch(batch)]) + } + } + ChunkableModuleOrBatch::None(i) => Ok(vec![ChunkableModuleOrBatch::None(i)]), + }) + .try_flat_join() + .await? + .into_iter() + .collect(); + let mut batch_groups = FxIndexSet::default(); for &module in &state.chunkable_items { if let Some(batch_group) = module_batches_graph.get_batch_group(&module.into()) { From 6118a549c03632cb099836a13f9f755a82aa071f Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 29 Apr 2025 17:05:52 +0200 Subject: [PATCH 08/59] codegen --- .../turbopack-ecmascript/src/code_gen.rs | 44 ++- .../crates/turbopack-ecmascript/src/lib.rs | 350 ++++++++++++++++-- .../src/references/esm/base.rs | 37 +- .../src/references/esm/binding.rs | 112 +++++- .../src/references/esm/export.rs | 91 +++-- 5 files changed, 531 insertions(+), 103 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/code_gen.rs b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs index bd77f1da1c9d4..133db172bfbae 100644 --- a/turbopack/crates/turbopack-ecmascript/src/code_gen.rs +++ b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs @@ -16,26 +16,29 @@ use turbopack_core::{ chunk::ChunkingContext, module_graph::ModuleGraph, reference::ModuleReference, }; -use crate::references::{ - AstPath, - amd::AmdDefineWithDependenciesCodeGen, - cjs::{ - CjsRequireAssetReferenceCodeGen, CjsRequireCacheAccess, - CjsRequireResolveAssetReferenceCodeGen, - }, - constant_condition::ConstantConditionCodeGen, - constant_value::ConstantValueCodeGen, - dynamic_expression::DynamicExpression, - esm::{ - EsmBinding, EsmModuleItem, ImportMetaBinding, ImportMetaRef, - dynamic::EsmAsyncAssetReferenceCodeGen, module_id::EsmModuleIdAssetReferenceCodeGen, - url::UrlAssetReferenceCodeGen, +use crate::{ + ScopeHoistingContext, + references::{ + AstPath, + amd::AmdDefineWithDependenciesCodeGen, + cjs::{ + CjsRequireAssetReferenceCodeGen, CjsRequireCacheAccess, + CjsRequireResolveAssetReferenceCodeGen, + }, + constant_condition::ConstantConditionCodeGen, + constant_value::ConstantValueCodeGen, + dynamic_expression::DynamicExpression, + esm::{ + EsmBinding, EsmModuleItem, ImportMetaBinding, ImportMetaRef, + dynamic::EsmAsyncAssetReferenceCodeGen, module_id::EsmModuleIdAssetReferenceCodeGen, + url::UrlAssetReferenceCodeGen, + }, + ident::IdentReplacement, + member::MemberReplacement, + require_context::RequireContextAssetReferenceCodeGen, + unreachable::Unreachable, + worker::WorkerAssetReferenceCodeGen, }, - ident::IdentReplacement, - member::MemberReplacement, - require_context::RequireContextAssetReferenceCodeGen, - unreachable::Unreachable, - worker::WorkerAssetReferenceCodeGen, }; #[derive(Default)] @@ -193,6 +196,7 @@ impl CodeGen { &self, g: Vc, ctx: Vc>, + scope_hoisting_context: Option>, ) -> Result { match self { Self::AmdDefineWithDependenciesCodeGen(v) => v.code_generation(g, ctx).await, @@ -200,7 +204,7 @@ impl CodeGen { Self::ConstantConditionCodeGen(v) => v.code_generation(g, ctx).await, Self::ConstantValueCodeGen(v) => v.code_generation(g, ctx).await, Self::DynamicExpression(v) => v.code_generation(g, ctx).await, - Self::EsmBinding(v) => v.code_generation(g, ctx).await, + Self::EsmBinding(v) => v.code_generation(g, ctx, scope_hoisting_context).await, Self::EsmModuleItem(v) => v.code_generation(g, ctx).await, Self::IdentReplacement(v) => v.code_generation(g, ctx).await, Self::ImportMetaBinding(v) => v.code_generation(g, ctx).await, diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 0e30add796a08..3962f157b5921 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -51,16 +51,17 @@ pub use references::{AnalyzeEcmascriptModuleResult, TURBOPACK_HELPER}; use serde::{Deserialize, Serialize}; pub use static_code::StaticEcmascriptCode; use swc_core::{ + atoms::Atom, base::SwcComments, common::{ - BytePos, DUMMY_SP, GLOBALS, Globals, Mark, SourceMap, + BytePos, DUMMY_SP, GLOBALS, Globals, Mark, SourceMap, SyntaxContext, comments::{Comment, Comments}, util::take::Take, }, ecma::{ - ast::{self, Expr, ModuleItem, Program, Script}, + ast::{self, Expr, Id, ModuleItem, Program, Script}, codegen::{Emitter, text_writer::JsWriter}, - visit::{VisitMutWith, VisitMutWithAstPath}, + visit::{VisitMut, VisitMutWith, VisitMutWithAstPath}, }, quote, }; @@ -85,7 +86,7 @@ use turbopack_core::{ context::AssetContext, ident::AssetIdent, module::{Module, OptionModule}, - module_graph::ModuleGraph, + module_graph::{ModuleGraph, merged_modules::MergedModules}, reference::ModuleReferences, reference_type::InnerAssets, resolve::{ @@ -316,12 +317,48 @@ pub trait EcmascriptAnalyzable: Module + Asset { module_graph: Vc, chunking_context: Vc>, async_module_info: Option>, - ) -> Vc { - EcmascriptModuleContent::new(self.module_content_options( - module_graph, - chunking_context, - async_module_info, - )) + ) -> Result> { + println!( + "additional {:?} {:?}", + self.ident().to_string().await?, + module_graph + .merged_modules() + .additional_modules_for_entry(Vc::upcast(self)) + .await? + .iter() + .map(|(m, _)| m.ident().to_string()) + .try_join() + .await?, + ); + + let own_options = + self.module_content_options(module_graph, chunking_context, async_module_info); + let additional_modules = module_graph + .merged_modules() + .additional_modules_for_entry(Vc::upcast(self)); + let additional_modules_ref = additional_modules.await?; + + if additional_modules_ref.is_empty() { + Ok(EcmascriptModuleContent::new(own_options)) + } else { + let additional_options = additional_modules_ref + .iter() + .map(|(m, _)| { + let Some(m) = ResolvedVc::try_downcast::>(*m) + else { + anyhow::bail!("Expected EcmascriptAnalyzable in scope hoisting group"); + }; + Ok(m.module_content_options(module_graph, chunking_context, async_module_info)) + }) + .collect::>>()?; + + Ok(EcmascriptModuleContent::new_merged( + Vc::upcast(self), + own_options, + additional_modules, + additional_options, + )) + } } } @@ -890,7 +927,10 @@ pub struct EcmascriptModuleContentOptions { } impl EcmascriptModuleContentOptions { - async fn merged_code_gens(&self) -> Result> { + async fn merged_code_gens( + &self, + scope_hoisting_context: Option>, + ) -> Result> { let EcmascriptModuleContentOptions { parsed, module_graph, @@ -924,7 +964,12 @@ impl EcmascriptModuleContentOptions { if let EcmascriptExports::EsmExports(exports) = *exports.await? { Some( exports - .code_generation(**chunking_context, Some(**parsed), *export_usage_info) + .code_generation( + **chunking_context, + scope_hoisting_context, + Some(**parsed), + *export_usage_info, + ) .await?, ) } else { @@ -935,7 +980,7 @@ impl EcmascriptModuleContentOptions { let esm_code_gens = esm_references .await? .iter() - .map(|r| r.code_generation(**chunking_context)) + .map(|r| r.code_generation(**chunking_context, scope_hoisting_context)) .try_join() .await?; @@ -948,7 +993,9 @@ impl EcmascriptModuleContentOptions { let code_gens = code_generation .await? .iter() - .map(|c| c.code_generation(**module_graph, **chunking_context)) + .map(|c| { + c.code_generation(**module_graph, **chunking_context, scope_hoisting_context) + }) .try_join() .await?; @@ -981,7 +1028,8 @@ impl EcmascriptModuleContent { chunking_context, .. } = &*input; - let code_gens = input.merged_code_gens().await?; + + let code_gens = input.merged_code_gens(None).await?; async { let minify = chunking_context.minify_type().await?; @@ -993,6 +1041,7 @@ impl EcmascriptModuleContent { *generate_source_map, *original_source_map, *minify, + false, ) .await?; emit_content(content).await @@ -1017,15 +1066,211 @@ impl EcmascriptModuleContent { generate_source_map, None, MinifyType::NoMinify, + false, ) .await?; emit_content(content).await } + + /// Creates a new [`Vc`] from multiple modules, performing scope + /// hoisting. + #[turbo_tasks::function] + pub async fn new_merged( + module: ResolvedVc>, + module_options: Vc, + additional_modules: Vc, + additional_options: Vec>, + ) -> Result> { + let additional_modules = additional_modules.await?; + + let modules = std::iter::once((module, true)) + .chain(additional_modules.iter().copied()) + .map(|(m, exposed)| { + ( + ResolvedVc::try_downcast::>(m).unwrap(), + exposed, + ) + }) + .collect::>(); + + let globals_merged = Globals::default(); + let merged_ctxts = GLOBALS.set(&globals_merged, || { + let exports_mark = Mark::new(); + FxIndexMap::from_iter(modules.keys().map(|m| { + ( + *m, + SyntaxContext::empty().apply_mark(Mark::fresh(exports_mark)), + ) + })) + }); + + let contents = std::iter::once(module_options) + .chain(additional_options.into_iter()) + .zip(modules.keys().copied()) + .map(async |(options, module)| { + let options = options.await?; + let EcmascriptModuleContentOptions { + chunking_context, + parsed, + ident, + specified_module_type, + generate_source_map, + original_source_map, + .. + } = &*options; + let var_name = parsed.await?; + let globals = if let ParseResult::Ok { globals, .. } = &*var_name { + globals + } else { + unreachable!() + }; + let (is_export_mark, module_marks) = GLOBALS.set(globals, || { + ( + Mark::new(), + FxIndexMap::from_iter(modules.keys().map(|m| (*m, Mark::new()))), + ) + }); + let ctx = ScopeHoistingContext { + module, + modules: &modules, + is_export_mark, + module_marks: &module_marks, + }; + let code_gens = options.merged_code_gens(Some(ctx)).await?; + Ok(( + module, + module_marks, + is_export_mark, + process_parse_result( + *parsed, + **ident, + *specified_module_type, + code_gens, + *generate_source_map, + *original_source_map, + *chunking_context.minify_type().await?, + true, + ) + .await?, + )) + }) + .try_join() + .await?; + + struct SetSyntaxContextVisitor<'a> { + current_module: ResolvedVc>, + // A marker to identify the special cross-module variable references + export_mark: Mark, + // The syntax contexts in the merged AST (each module has its own) + merged_ctxts: + &'a FxIndexMap>, SyntaxContext>, + // The export marks in the current AST, which will be mapped to merged_ctxts + current_module_marks: + &'a FxIndexMap>, Mark>, + } + impl VisitMut for SetSyntaxContextVisitor<'_> { + fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { + let module = if ctxt.has_mark(self.export_mark) { + *self + .current_module_marks + .iter() + .filter_map(|(module, mark)| { + if ctxt.has_mark(*mark) { + Some(module) + } else { + None + } + }) + .next() + .unwrap() + } else { + self.current_module + }; + + *ctxt = *self.merged_ctxts.get(&module).unwrap(); + } + // fn visit_mut_span(&mut self, span: &mut Span) {} + } + + // TODO properly merge ASTs: + // - somehow merge the SourceMap struct + let merged_ast = { + let mut merged_ast = Program::Module(swc_core::ecma::ast::Module { + span: DUMMY_SP, + shebang: None, + body: contents + .into_iter() + .flat_map(|(module, module_marks, export_mark, content)| { + if let CodeGenResult { + program: Program::Module(mut content), + globals, + .. + } = content + { + GLOBALS.set(&*globals, || { + content.visit_mut_with(&mut SetSyntaxContextVisitor { + current_module: module, + export_mark, + merged_ctxts: &merged_ctxts, + current_module_marks: &module_marks, + }); + }); + + content.body.clone() + } else { + unreachable!() + } + }) + .collect(), + }); + GLOBALS.set(&globals_merged, || { + merged_ast + .visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); + }); + merged_ast + }; + let content = CodeGenResult { + program: merged_ast, + source_map: Arc::new(SourceMap::default()), + globals: Arc::new(globals_merged), + comments: Either::Left(Default::default()), + is_esm: true, + generate_source_map: false, + original_source_map: None, + minify: *module_options + .first() + .unwrap() + .await? + .chunking_context + .minify_type() + .await?, + extra_comments: SwcComments::default(), + }; + emit_content(content).await + } +} + +#[allow(clippy::type_complexity)] +// struct DisplayContextVisitor { +// postfix: &'static str, +// } +// impl VisitMut for DisplayContextVisitor { +// fn visit_mut_ident(&mut self, ident: &mut Ident) { +// ident.sym = format!("{}$$${}{}", ident.sym, self.postfix, ident.ctxt.as_u32()).into(); +// } +// } +#[derive(Clone, Copy)] +pub struct ScopeHoistingContext<'a> { + module: ResolvedVc>, + modules: &'a FxIndexMap>, bool>, + is_export_mark: Mark, + module_marks: &'a FxIndexMap>, Mark>, } struct CodeGenResult { program: Program, source_map: Arc, + globals: Arc, comments: Either>, extra_comments: SwcComments, is_esm: bool, @@ -1042,6 +1287,7 @@ async fn process_parse_result( generate_source_map: bool, original_source_map: Option>>, minify: MinifyType, + retain_syntax_context: bool, ) -> Result { let parsed = parsed.final_read_hint().await?; @@ -1096,12 +1342,7 @@ async fn process_parse_result( let top_level_mark = eval_context.top_level_mark; let is_esm = eval_context.is_esm(specified_module_type); - process_content_with_code_gens( - &mut program, - globals, - Some(top_level_mark), - &mut code_gens, - ); + process_content_with_code_gens(&mut program, globals, &mut code_gens); for comments in code_gens.iter_mut().flat_map(|cg| cg.comments.as_mut()) { let leading = Arc::unwrap_or_clone(take(&mut comments.leading)); @@ -1116,9 +1357,33 @@ async fn process_parse_result( } } + GLOBALS.set(globals, || { + if retain_syntax_context { + program.visit_mut_with(&mut hygiene_rename_only(Some(top_level_mark))); + } else { + program.visit_mut_with( + &mut swc_core::ecma::transforms::base::hygiene::hygiene_with_config( + swc_core::ecma::transforms::base::hygiene::Config { + top_level_mark, + ..Default::default() + }, + ), + ); + } + // program.visit_mut_with(&mut DisplayContextVisitor { + // postfix: "individual", + // }); + program.visit_mut_with(&mut swc_core::ecma::transforms::base::fixer::fixer(None)); + + // we need to remove any shebang before bundling as it's only valid as the first + // line in a js file (not in a chunk item wrapped in the runtime) + remove_shebang(&mut program); + }); + CodeGenResult { program, source_map: source_map.clone(), + globals: globals.clone(), comments, extra_comments, is_esm, @@ -1150,6 +1415,7 @@ async fn process_parse_result( shebang: None, }), source_map: Arc::new(SourceMap::default()), + globals: Arc::new(Globals::default()), comments: Either::Left(Default::default()), extra_comments: Default::default(), is_esm: false, @@ -1176,6 +1442,7 @@ async fn process_parse_result( shebang: None, }), source_map: Arc::new(SourceMap::default()), + globals: Arc::new(Globals::default()), comments: Either::Left(Default::default()), extra_comments: Default::default(), is_esm: false, @@ -1197,6 +1464,7 @@ async fn emit_content(content: CodeGenResult) -> Result = vec![]; @@ -1273,7 +1541,6 @@ async fn emit_content(content: CodeGenResult) -> Result, code_gens: &mut Vec, ) { let mut visitors = Vec::new(); @@ -1307,19 +1574,6 @@ fn process_content_with_code_gens( for pass in root_visitors { program.modify(pass); } - program.visit_mut_with( - &mut swc_core::ecma::transforms::base::hygiene::hygiene_with_config( - swc_core::ecma::transforms::base::hygiene::Config { - top_level_mark: top_level_mark.unwrap_or_default(), - ..Default::default() - }, - ), - ); - program.visit_mut_with(&mut swc_core::ecma::transforms::base::fixer::fixer(None)); - - // we need to remove any shebang before bundling as it's only valid as the first - // line in a js file (not in a chunk item wrapped in the runtime) - remove_shebang(program); }); match program { @@ -1343,6 +1597,32 @@ fn process_content_with_code_gens( }; } +/// Like `hygiene`, but only renames the Atoms without clearing all SyntaxContexts +fn hygiene_rename_only(top_level_mark: Option) -> impl VisitMut { + struct HygieneRenamer; + impl swc_core::ecma::transforms::base::rename::Renamer for HygieneRenamer { + const MANGLE: bool = false; + const RESET_N: bool = true; + + fn new_name_for(&self, orig: &Id, n: &mut usize) -> Atom { + let res = if *n == 0 { + orig.0.clone() + } else { + format!("{}{}", orig.0, n).into() + }; + *n += 1; + res + } + } + swc_core::ecma::transforms::base::rename::renamer( + swc_core::ecma::transforms::base::hygiene::Config { + top_level_mark: top_level_mark.unwrap_or_default(), + ..Default::default() + }, + HygieneRenamer, + ) +} + struct MergedComments where A: Comments, diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index b4e6f87682773..8d96aa25dffc6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -32,7 +32,7 @@ use turbopack_resolve::ecmascript::esm_resolve; use super::export::{all_known_export_names, is_export_missing}; use crate::{ - TreeShakingMode, + ScopeHoistingContext, TreeShakingMode, analyzer::imports::ImportAnnotations, chunk::EcmascriptChunkPlaceable, code_gen::CodeGeneration, @@ -304,6 +304,7 @@ impl EsmAssetReference { pub async fn code_generation( self: Vc, chunking_context: Vc>, + scope_hoisting_context: Option>, ) -> Result { let this = &*self.await?; @@ -333,20 +334,28 @@ impl EsmAssetReference { unreachable!() } ReferencedAsset::Some(asset) => { - let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; - let name = ident; - Some(( - id.to_string().into(), - var_decl_with_span( - quote!( - "var $name = $turbopack_import($id);" as Stmt, - name = Ident::new(name.clone().into(), DUMMY_SP, Default::default()), - turbopack_import: Expr = TURBOPACK_IMPORT.into(), - id: Expr = module_id_to_lit(&id), + if scope_hoisting_context + .is_some_and(|c| c.modules.contains_key(&ResolvedVc::upcast(*asset))) + { + // No need to import, the module is already available in the same scope + // hoisting group. + None + } else { + let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; + let name = ident; + Some(( + id.to_string().into(), + var_decl_with_span( + quote!( + "var $name = $turbopack_import($id);" as Stmt, + name = Ident::new(name.clone().into(), DUMMY_SP, Default::default()), + turbopack_import: Expr = TURBOPACK_IMPORT.into(), + id: Expr = module_id_to_lit(&id), + ), + span, ), - span, - ), - )) + )) + } } ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => { if !*chunking_context diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs index c11187ddfd1b5..cdfb78cd008df 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -1,7 +1,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use swc_core::{ - common::Span, + common::{Mark, Span, SyntaxContext}, ecma::{ ast::{ ComputedPropName, Expr, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, Number, Prop, @@ -16,9 +16,14 @@ use turbopack_core::{chunk::ChunkingContext, module_graph::ModuleGraph}; use super::EsmAssetReference; use crate::{ + ScopeHoistingContext, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGen, CodeGeneration}, create_visitor, - references::{AstPath, esm::base::ReferencedAsset}, + references::{ + AstPath, + esm::{EsmExport, base::ReferencedAsset}, + }, }; #[derive(Hash, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, TraceRawVcs, NonLocalValue)] @@ -45,20 +50,55 @@ impl EsmBinding { &self, _module_graph: Vc, chunking_context: Vc>, + scope_hoisting_context: Option>, ) -> Result { let mut visitors = vec![]; let export = self.export.clone(); - let imported_module = self.reference.get_referenced_asset(); + let imported_module = self.reference.get_referenced_asset().await?; enum ImportedIdent { Module(String), + Local(RcStr, [Mark; 2]), None, Unresolvable, } - let imported_ident = match &*imported_module.await? { + let imported_ident = match &*imported_module { ReferencedAsset::None => ImportedIdent::None, + ReferencedAsset::Some(module) => { + let mut result = None; + if let Some(scope_hoisting_context) = scope_hoisting_context { + if let Some(mark) = scope_hoisting_context + .module_marks + .get(&ResolvedVc::upcast(*module)) + { + if let Some(export) = &export { + if let EcmascriptExports::EsmExports(exports) = + *module.get_exports().await? + { + let exports = exports.await?; + let export = exports.exports.get(export); + if let Some(EsmExport::LocalBinding(name, _)) = export { + result = Some(ImportedIdent::Local( + name.clone(), + [*mark, scope_hoisting_context.is_export_mark], + )); + } else { + // TODO + } + } + } + } + } + if let Some(result) = result { + result + } else { + ImportedIdent::Module( + imported_module.get_ident(chunking_context).await?.unwrap(), + ) + } + } imported_module => imported_module .get_ident(chunking_context) .await? @@ -80,7 +120,7 @@ impl EsmBinding { ImportedIdent::Module(imported_ident) => { *prop = Prop::KeyValue(KeyValueProp { key: PropName::Ident(ident.clone().into()), - value: Box::new(make_expr( + value: Box::new(make_module_expr( imported_ident, export.as_deref(), ident.span, @@ -89,11 +129,26 @@ impl EsmBinding { }); } ImportedIdent::None => { + *prop = Prop::KeyValue(KeyValueProp { key: PropName::Ident(ident.clone().into()), - value: Expr::undefined(ident.span), + value: + Expr::undefined(ident.span), }); } + ImportedIdent::Local(local_ident, marks) => { + *prop = Prop::KeyValue( + KeyValueProp { + key: PropName::Ident(ident.clone().into()), + value: Box::new(make_local_expr( + local_ident, + export.as_deref(), + ident.span, + *marks + ).into()), + } + ); + } ImportedIdent::Unresolvable => { // Do nothing, the reference will insert a throw } @@ -118,7 +173,15 @@ impl EsmBinding { use swc_core::common::Spanned; match &imported_ident { ImportedIdent::Module(imported_ident) => { - *expr = make_expr(imported_ident, export.as_deref(), expr.span(), in_call); + *expr = make_module_expr(imported_ident, export.as_deref(), expr.span(), in_call); + } + ImportedIdent::Local(local_ident, marks) => { + *expr = make_local_expr( + local_ident, + export.as_deref(), + expr.span(), + *marks + ).into(); } ImportedIdent::None => { *expr = *Expr::undefined(expr.span()); @@ -149,12 +212,15 @@ impl EsmBinding { use swc_core::common::Spanned; match &imported_ident { ImportedIdent::Module(imported_ident) => { - *l = match make_expr(imported_ident, export.as_deref(), l.span(), false) { + *l = match make_module_expr(imported_ident, export.as_deref(), l.span(), false) { Expr::Ident(ident) => SimpleAssignTarget::Ident(ident.into()), Expr::Member(member) => SimpleAssignTarget::Member(member), _ => unreachable!(), }; } + ImportedIdent::Local(local_ident, marks) => { + *l = SimpleAssignTarget::Ident(make_local_expr(local_ident, export.as_deref(), l.span(), *marks).into()); + } ImportedIdent::None => { // Do nothing, cannot assign to `undefined` } @@ -183,7 +249,12 @@ impl From for CodeGen { } } -fn make_expr(imported_module: &str, export: Option<&str>, span: Span, in_call: bool) -> Expr { +fn make_module_expr( + imported_module: &str, + export: Option<&str>, + span: Span, + in_call: bool, +) -> Expr { if let Some(export) = export { let mut expr = Expr::Member(MemberExpr { span, @@ -219,3 +290,26 @@ fn make_expr(imported_module: &str, export: Option<&str>, span: Span, in_call: b Expr::Ident(Ident::new(imported_module.into(), span, Default::default())) } } + +fn make_local_expr( + local_module: &str, + _export: Option<&str>, + span: Span, + marks: [Mark; 2], +) -> Ident { + // if let Some(export) = export { + // Ident::new( + // format!("{local_module}_{export}").into(), + // span, + // Default::default(), + // ) + // } else { + Ident::new( + local_module.into(), + span, + SyntaxContext::empty() + .apply_mark(marks[0]) + .apply_mark(marks[1]), + ) + // } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index ffdaa6fe8d929..159c11048f8f7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -18,7 +18,7 @@ use turbo_tasks::{ }; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ - chunk::ChunkingContext, + chunk::{ChunkingContext, ModuleChunkItemIdExt}, ident::AssetIdent, issue::{IssueExt, IssueSeverity, StyledString, analyze::AnalyzeIssue}, module::Module, @@ -28,7 +28,7 @@ use turbopack_core::{ use super::base::ReferencedAsset; use crate::{ - EcmascriptModuleAsset, + EcmascriptModuleAsset, ScopeHoistingContext, chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, magic_identifier, @@ -36,6 +36,7 @@ use crate::{ runtime_functions::{TURBOPACK_DYNAMIC, TURBOPACK_ESM}, simple_tree_shake::ModuleExportUsageInfo, tree_shake::asset::EcmascriptModulePartAsset, + utils::module_id_to_lit, }; #[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue)] @@ -556,6 +557,7 @@ impl EsmExports { pub async fn code_generation( self: Vc, chunking_context: Vc>, + scope_hoisting_context: Option>, parsed: Option>, export_usage_info: Option>, ) -> Result { @@ -579,28 +581,33 @@ impl EsmExports { )); } - let mut props = Vec::new(); + let mut getters = Vec::new(); for (exported, local) in &expanded.exports { let expr = match local { EsmExport::Error => Some(quote!( "(() => { throw new Error(\"Failed binding. See build errors!\"); })" as Expr, )), EsmExport::LocalBinding(name, mutable) => { - let local = if name == "default" { - Cow::Owned(magic_identifier::mangle("default export")) + let (local, ctxt) = if name == "default" { + ( + Cow::Owned(magic_identifier::mangle("default export")), + Default::default(), + ) } else { - Cow::Borrowed(name.as_str()) + ( + Cow::Borrowed(name.as_str()), + parsed + .as_ref() + .and_then(|parsed| { + if let ParseResult::Ok { eval_context, .. } = &**parsed { + eval_context.imports.exports.get(name).map(|id| id.1) + } else { + None + } + }) + .unwrap_or_default(), + ) }; - let ctxt = parsed - .as_ref() - .and_then(|parsed| { - if let ParseResult::Ok { eval_context, .. } = &**parsed { - eval_context.imports.exports.get(name).map(|id| id.1) - } else { - None - } - }) - .unwrap_or_default(); if *mutable { Some(quote!( @@ -671,7 +678,7 @@ impl EsmExports { } }; if let Some(expr) = expr { - props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + getters.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { key: PropName::Str(Str { span: DUMMY_SP, value: exported.as_str().into(), @@ -683,7 +690,7 @@ impl EsmExports { } let getters = Expr::Object(ObjectLit { span: DUMMY_SP, - props, + props: getters, }); let dynamic_stmt = if !dynamic_exports.is_empty() { Some(Stmt::Expr(ExprStmt { @@ -694,6 +701,46 @@ impl EsmExports { None }; + let early_hoisted_stmts = if let Some(scope_hoisting_context) = scope_hoisting_context { + let exposed = *scope_hoisting_context + .modules + .get(&scope_hoisting_context.module) + .unwrap(); + let registry = if exposed { + Some(CodeGenerationHoistedStmt::new( + "__turbopack_esm__".into(), + { + let id = scope_hoisting_context + .module + .chunk_item_id(Vc::upcast(chunking_context)) + .await?; + quote!("$turbopack_esm_other($id, $getters);" as Stmt, + turbopack_esm_other: Expr = TURBOPACK_ESM_OTHER.into(), + id: Expr = module_id_to_lit(&id), + getters: Expr = getters + ) + }, + )) + } else { + None + }; + + let local_re_bindings = vec![]; + + registry + .into_iter() + .chain(local_re_bindings.into_iter()) + .collect() + } else { + vec![CodeGenerationHoistedStmt::new( + "__turbopack_esm__".into(), + quote!("$turbopack_esm($getters);" as Stmt, + turbopack_esm: Expr = TURBOPACK_ESM.into(), + getters: Expr = getters + ), + )] + }; + Ok(CodeGeneration::new( vec![], [dynamic_stmt @@ -701,13 +748,7 @@ impl EsmExports { .into_iter() .flatten() .collect(), - vec![CodeGenerationHoistedStmt::new( - "__turbopack_esm__".into(), - quote!("$turbopack_esm($getters);" as Stmt, - turbopack_esm: Expr = TURBOPACK_ESM.into(), - getters: Expr = getters - ), - )], + early_hoisted_stmts, )) } } From 4e586682e59e27fe556d224c90bf7e4bc867c7a5 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 8 May 2025 15:43:46 +0200 Subject: [PATCH 09/59] MergedEcmascriptModule --- .../crates/turbopack-ecmascript/src/lib.rs | 75 +++----- .../turbopack-ecmascript/src/merged_module.rs | 160 ++++++++++++++++++ 2 files changed, 179 insertions(+), 56 deletions(-) create mode 100644 turbopack/crates/turbopack-ecmascript/src/merged_module.rs diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 3962f157b5921..2ad22101bdf50 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -16,6 +16,7 @@ pub mod code_gen; mod errors; pub mod magic_identifier; pub mod manifest; +mod merged_module; pub mod minify; pub mod parse; mod path_visitor; @@ -86,7 +87,7 @@ use turbopack_core::{ context::AssetContext, ident::AssetIdent, module::{Module, OptionModule}, - module_graph::{ModuleGraph, merged_modules::MergedModules}, + module_graph::ModuleGraph, reference::ModuleReferences, reference_type::InnerAssets, resolve::{ @@ -103,6 +104,7 @@ use self::chunk::{EcmascriptChunkItemContent, EcmascriptChunkType, EcmascriptExp use crate::{ chunk::{EcmascriptChunkPlaceable, placeable::is_marked_as_side_effect_free}, code_gen::{CodeGens, ModifiableAst}, + merged_module::MergedEcmascriptModule, parse::generate_js_source_map, references::{ analyse_ecmascript_module, async_module::OptionAsyncModule, esm::base::EsmAssetReferences, @@ -318,47 +320,9 @@ pub trait EcmascriptAnalyzable: Module + Asset { chunking_context: Vc>, async_module_info: Option>, ) -> Result> { - println!( - "additional {:?} {:?}", - self.ident().to_string().await?, - module_graph - .merged_modules() - .additional_modules_for_entry(Vc::upcast(self)) - .await? - .iter() - .map(|(m, _)| m.ident().to_string()) - .try_join() - .await?, - ); - let own_options = self.module_content_options(module_graph, chunking_context, async_module_info); - let additional_modules = module_graph - .merged_modules() - .additional_modules_for_entry(Vc::upcast(self)); - let additional_modules_ref = additional_modules.await?; - - if additional_modules_ref.is_empty() { - Ok(EcmascriptModuleContent::new(own_options)) - } else { - let additional_options = additional_modules_ref - .iter() - .map(|(m, _)| { - let Some(m) = ResolvedVc::try_downcast::>(*m) - else { - anyhow::bail!("Expected EcmascriptAnalyzable in scope hoisting group"); - }; - Ok(m.module_content_options(module_graph, chunking_context, async_module_info)) - }) - .collect::>>()?; - - Ok(EcmascriptModuleContent::new_merged( - Vc::upcast(self), - own_options, - additional_modules, - additional_options, - )) - } + Ok(EcmascriptModuleContent::new(own_options)) } } @@ -781,9 +745,11 @@ impl MergeableModule for EcmascriptModuleAsset { Ok(MergeableModuleResult::Merged { consumed: consumed_modules.len() as u32, skipped, - merged_module: todo!(), - // TODO - // merged_module: MergedEcmascriptModule::new(consumed_modules) + merged_module: ResolvedVc::upcast(MergedEcmascriptModule::new( + consumed_modules, + // TODO where to get options from? + self.options().to_resolved().await?, + )), } .cell()) } else { @@ -1076,19 +1042,16 @@ impl EcmascriptModuleContent { /// hoisting. #[turbo_tasks::function] pub async fn new_merged( - module: ResolvedVc>, - module_options: Vc, - additional_modules: Vc, - additional_options: Vec>, + modules: Vec>>, + module_options: Vec>, ) -> Result> { - let additional_modules = additional_modules.await?; - - let modules = std::iter::once((module, true)) - .chain(additional_modules.iter().copied()) - .map(|(m, exposed)| { + let modules = modules + .iter() + .map(|m| { ( - ResolvedVc::try_downcast::>(m).unwrap(), - exposed, + ResolvedVc::try_sidecast::>(*m).unwrap(), + // TODO when is a module exposed? + true, ) }) .collect::>(); @@ -1104,8 +1067,8 @@ impl EcmascriptModuleContent { })) }); - let contents = std::iter::once(module_options) - .chain(additional_options.into_iter()) + let contents = module_options + .iter() .zip(modules.keys().copied()) .map(async |(options, module)| { let options = options.await?; diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs new file mode 100644 index 0000000000000..b2685bfc98a36 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -0,0 +1,160 @@ +use anyhow::Result; +use turbo_tasks::{ResolvedVc, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + ident::AssetIdent, + module::Module, + module_graph::ModuleGraph, + reference::ModuleReferences, +}; + +use crate::{ + EcmascriptAnalyzable, EcmascriptModuleContent, EcmascriptOptions, + chunk::{EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType}, +}; + +#[turbo_tasks::value(shared)] +pub(crate) struct MergedEcmascriptModule { + modules: Vec>>, + options: ResolvedVc, +} + +impl MergedEcmascriptModule { + pub fn new( + modules: Vec>>, + options: ResolvedVc, + ) -> ResolvedVc { + MergedEcmascriptModule { modules, options }.resolved_cell() + } +} + +#[turbo_tasks::value_impl] +impl Asset for MergedEcmascriptModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + panic!("content() should not be called"); + } +} + +#[turbo_tasks::value_impl] +impl Module for MergedEcmascriptModule { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + // This purposely reuses the module's ident as it has replaced the original module, thus + // there can never be a collision. + self.modules.first().unwrap().ident() + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + panic!("references() should not be called"); + } + + #[turbo_tasks::function] + async fn is_self_async(&self) -> Result> { + panic!("is_self_async() should not be called"); + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for MergedEcmascriptModule { + #[turbo_tasks::function] + fn as_chunk_item( + self: ResolvedVc, + module_graph: ResolvedVc, + chunking_context: ResolvedVc>, + ) -> Vc> { + Vc::upcast( + MergedEcmascriptModuleChunkItem { + module: self, + module_graph, + chunking_context, + } + .cell(), + ) + } +} + +#[turbo_tasks::value] +struct MergedEcmascriptModuleChunkItem { + module: ResolvedVc, + module_graph: ResolvedVc, + chunking_context: ResolvedVc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for MergedEcmascriptModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + *ResolvedVc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + *ResolvedVc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should not be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let module = self.module.await?; + let modules = &module.modules; + println!( + "merged chunk item: {:?}", + modules + .iter() + .map(|m| m.ident().to_string()) + .try_join() + .await? + ); + let options = modules + .iter() + .map(|m| { + let Some(m) = ResolvedVc::try_downcast::>(*m) else { + anyhow::bail!("Expected EcmascriptAnalyzable in scope hoisting group"); + }; + Ok(m.module_content_options( + *self.module_graph, + *self.chunking_context, + async_module_info, + )) + }) + .collect::>>()?; + + let content = + EcmascriptModuleContent::new_merged(modules.iter().map(|m| **m).collect(), options); + + // TODO async + let async_module_options = Vc::cell(None); + + Ok(EcmascriptChunkItemContent::new( + content, + *self.chunking_context, + *module.options, + async_module_options, + )) + } +} From 7be67a7289eff57dfac1da4396785d389ce467b1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 9 May 2025 13:34:11 +0200 Subject: [PATCH 10/59] Emit additional id list --- .../turbopack-ecmascript/src/chunk/item.rs | 19 ++++++++++--- .../crates/turbopack-ecmascript/src/lib.rs | 27 ++++++++++++++----- .../src/references/external_module.rs | 1 + .../src/tree_shake/chunk_item.rs | 1 + 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs index 6d289d741ec63..9b1bebe35b563 100644 --- a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs @@ -2,12 +2,14 @@ use std::io::Write; use anyhow::{Result, bail}; use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; use turbo_tasks::{ - NonLocalValue, ResolvedVc, TaskInput, Upcast, ValueToString, Vc, trace::TraceRawVcs, + NonLocalValue, ResolvedVc, TaskInput, TryJoinIterExt, Upcast, ValueToString, Vc, + trace::TraceRawVcs, }; use turbo_tasks_fs::{FileSystemPath, rope::Rope}; use turbopack_core::{ - chunk::{AsyncModuleInfo, ChunkItem, ChunkItemWithAsyncModuleInfo, ChunkingContext}, + chunk::{AsyncModuleInfo, ChunkItem, ChunkItemWithAsyncModuleInfo, ChunkingContext, ModuleId}, code_builder::{Code, CodeBuilder}, error::PrettyPrintError, issue::{IssueExt, IssueSeverity, StyledString, code_gen::CodeGenerationIssue}, @@ -17,7 +19,7 @@ use turbopack_core::{ use crate::{ EcmascriptModuleContent, EcmascriptOptions, references::async_module::{AsyncModuleOptions, OptionAsyncModuleOptions}, - utils::FormatIter, + utils::{FormatIter, StringifyJs}, }; #[turbo_tasks::value(shared)] @@ -25,6 +27,7 @@ use crate::{ pub struct EcmascriptChunkItemContent { pub inner_code: Rope, pub source_map: Option, + pub additional_ids: SmallVec<[ResolvedVc; 1]>, pub options: EcmascriptChunkItemOptions, pub rewrite_source_path: Option>, pub placeholder_for_future_extensions: (), @@ -56,6 +59,7 @@ impl EcmascriptChunkItemContent { }, inner_code: content.inner_code.clone(), source_map: content.source_map.clone(), + additional_ids: content.additional_ids.clone(), options: if content.is_esm { EcmascriptChunkItemOptions { strict: true, @@ -104,7 +108,12 @@ impl EcmascriptChunkItemContent { args.push("w: __turbopack_wasm__"); args.push("u: __turbopack_wasm_module__"); } + let mut code = CodeBuilder::default(); + let additional_ids = self.additional_ids.iter().try_join().await?; + if !additional_ids.is_empty() { + code += "[" + } if self.options.this { code += "(function(__turbopack_context__) {\n"; } else { @@ -147,6 +156,10 @@ impl EcmascriptChunkItemContent { } code += "})"; + if !additional_ids.is_empty() { + writeln!(code, ", {}]", StringifyJs(&additional_ids))?; + } + Ok(code.build().cell()) } } diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 2ad22101bdf50..07f966e96ac58 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -50,6 +50,7 @@ use path_visitor::ApplyVisitors; use references::esm::UrlRewriteBehavior; pub use references::{AnalyzeEcmascriptModuleResult, TURBOPACK_HELPER}; use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; pub use static_code::StaticEcmascriptCode; use swc_core::{ atoms::Atom, @@ -81,7 +82,8 @@ use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, - MergeableModule, MergeableModuleResult, MergeableModules, MinifyType, + MergeableModule, MergeableModuleResult, MergeableModules, MinifyType, ModuleChunkItemIdExt, + ModuleId, }, compile_time_info::CompileTimeInfo, context::AssetContext, @@ -869,7 +871,7 @@ pub struct EcmascriptModuleContent { pub inner_code: Rope, pub source_map: Option, pub is_esm: bool, - // pub refresh: bool, + pub additional_ids: SmallVec<[ResolvedVc; 1]>, } #[turbo_tasks::value(shared)] @@ -1010,7 +1012,7 @@ impl EcmascriptModuleContent { false, ) .await?; - emit_content(content).await + emit_content(content, Default::default()).await } .instrument(tracing::info_span!("gen content with code gens")) .await @@ -1035,7 +1037,7 @@ impl EcmascriptModuleContent { false, ) .await?; - emit_content(content).await + emit_content(content, Default::default()).await } /// Creates a new [`Vc`] from multiple modules, performing scope @@ -1209,7 +1211,16 @@ impl EcmascriptModuleContent { .await?, extra_comments: SwcComments::default(), }; - emit_content(content).await + let chunking_context = module_options.first().unwrap().await?.chunking_context; + let additional_ids = modules + .keys() + .skip(1) + .map(|m| m.chunk_item_id(*chunking_context).to_resolved()) + .try_join() + .await? + .into(); + + emit_content(content, additional_ids).await } } @@ -1417,7 +1428,10 @@ async fn process_parse_result( }) } -async fn emit_content(content: CodeGenResult) -> Result> { +async fn emit_content( + content: CodeGenResult, + additional_ids: SmallVec<[ResolvedVc; 1]>, +) -> Result> { let CodeGenResult { program, source_map, @@ -1497,6 +1511,7 @@ async fn emit_content(content: CodeGenResult) -> Result Date: Mon, 12 May 2025 14:08:09 +0200 Subject: [PATCH 11/59] MergedModules per group bitmaps --- .../src/module_graph/merged_modules.rs | 248 ++++++++++++------ 1 file changed, 174 insertions(+), 74 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 7551fbb83be6b..00def53c0c00e 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -1,15 +1,21 @@ -use std::cmp::Ordering; +use std::{cmp::Ordering, collections::hash_map::Entry}; use anyhow::Result; +use roaring::RoaringBitmap; use rustc_hash::{FxHashMap, FxHashSet}; -use turbo_tasks::{FxIndexSet, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc}; +use turbo_tasks::{ + FxIndexMap, FxIndexSet, ReadRef, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc, +}; use crate::{ chunk::{ ChunkableModule, ChunkingType, MergeableModule, MergeableModuleResult, MergeableModules, }, module::Module, - module_graph::{GraphTraversalAction, ModuleGraph}, + module_graph::{ + GraphTraversalAction, ModuleGraph, SingleModuleGraphModuleNode, + chunk_group_info::RoaringBitmapWrapper, + }, }; #[turbo_tasks::value(transparent)] @@ -87,90 +93,184 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>>>, - /// For each module, the lists it is imported into (may be multiple). - current_list_indices: FxHashMap>, usize>, - } - let mut state = State { - lists: vec![], - current_list_indices: FxHashMap::default(), - }; - module_graph - .traverse_edges_from_entries_topological( - chunk_group.entries(), - &mut state, - |parent_info, node, state| { + + let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = + FxHashMap::default(); + let mut next_index = 0u32; + + let visit_count = module_graph + .traverse_edges_fixed_point( + chunk_group.entries().map(|e| (e, 0)), + &mut module_merged_groups, + |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, + node: &'_ SingleModuleGraphModuleNode, + module_merged_groups: &mut FxHashMap< + ResolvedVc>, + RoaringBitmapWrapper, + >| + -> GraphTraversalAction { // On the down traversal, establish which edges are mergable and set the list // indices. + if parent_info.is_some_and(|p| !p.1.is_parallel()) { - return Ok(GraphTraversalAction::Exclude); + // We are only interested in this particular chunk group + return GraphTraversalAction::Exclude; } - let (parent_module, hoisted) = - parent_info.map_or((None, false), |(node, ty)| { - ( - Some(node.module), - match ty { - ChunkingType::Parallel { hoisted, .. } => *hoisted, - _ => unreachable!(), - }, - ) - }); + let (parent, hoisted) = parent_info.map_or((None, false), |(node, ty)| { + ( + Some(node.module), + match ty { + ChunkingType::Parallel { hoisted, .. } => *hoisted, + _ => unreachable!(), + }, + ) + }); let module = node.module; - if ResolvedVc::try_downcast::>(module).is_some() { - let idx = if hoisted - && parent_module.is_some_and(|p| { - ResolvedVc::try_downcast::>(p).is_some() - }) { - // An eligible edge: MergeableModule ---hoisted---> MergeableModule - // Reuse the parent's list to later add the child to it - parent_module - .and_then(|p| state.current_list_indices.get(&p).copied()) - .unwrap_or_else(|| { - let idx = state.lists.len(); - state.lists.push(Default::default()); - idx - }) + if let (Some(parent_module), true) = (parent, hoisted) { + // Mergable with parent, inherit from parent + if parent_module == node.module { + // A self-reference + GraphTraversalAction::Skip } else { - // The module get its own list - let idx = state.lists.len(); - state.lists.push(Default::default()); - idx - }; - state.current_list_indices.insert(module, idx); - } - Ok(GraphTraversalAction::Continue) - }, - |_parent_info, node, state| { - // On the up traversal (which corresponds to execution order), add the module to - // the lists it belongs to. - let module = node.module; - // TODO when is a module exposed? - // let is_exposed = parent_info.is_none(); - - if let Some(mergable_module) = - ResolvedVc::try_downcast::>(module) - { - let idx = *state.current_list_indices.get(&module).unwrap(); - let list = state.lists.get_mut(idx).unwrap(); - - // We might visit the module multiple times, but only add it the first time - // (which corresponds to when it executes). - if list.insert(mergable_module) { - lists_reverse_map.entry(mergable_module).or_default().push( - ListOccurence { - list: idx, - entry: list.len(), - }, - ); + module_merged_groups.entry(node.module).or_default(); + let [Some(parent_merged_groups), Some(current_merged_groups)] = + module_merged_groups + .get_disjoint_mut([&parent_module, &node.module]) + else { + // All modules are inserted in the previous iteration + unreachable!() + }; + + if current_merged_groups.is_empty() { + // Initial visit, clone instead of merging + *current_merged_groups = parent_merged_groups.clone(); + GraphTraversalAction::Continue + } else if parent_merged_groups.is_proper_superset(current_merged_groups) + { + // Add bits from parent, and continue traversal because changed + **current_merged_groups |= &**parent_merged_groups; + GraphTraversalAction::Continue + } else { + // Unchanged, no need to forward to children + GraphTraversalAction::Skip + } + } + } else { + // Either a non-hoisted reference, or an incompatible parent, create a new + // group + let idx = next_index; + next_index += 1; + + match module_merged_groups.entry(module) { + Entry::Occupied(mut entry) => { + let current = entry.get_mut(); + if !current.contains(idx) { + // Mark and continue traversal because modified + current.insert(idx); + GraphTraversalAction::Continue + } else { + // Unchanged, no need to forward to children + GraphTraversalAction::Skip + } + } + Entry::Vacant(entry) => { + // First visit + entry.insert(RoaringBitmapWrapper( + RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), + )); + GraphTraversalAction::Continue + } } } }, + |_, _| 0, ) .await?; - lists.extend(state.lists); + let mut foo: FxIndexMap>> = Default::default(); + for (k, v) in &module_merged_groups { + foo.entry(v.clone()) + .or_default() + .push(k.ident().to_string().await?); + } + println!("{} {} {:#?}", visit_count, module_merged_groups.len(), foo); + + // module_graph + // .traverse_edges_from_entries_topological( + // chunk_group.entries(), + // &mut state, + // |parent_info, node, state| { + // // On the down traversal, establish which edges are mergable and set the list + // // indices. + // if parent_info.is_some_and(|p| !p.1.is_parallel()) { + // return Ok(GraphTraversalAction::Exclude); + // } + // let (parent_module, hoisted) = + // parent_info.map_or((None, false), |(node, ty)| { + // ( + // Some(node.module), + // match ty { + // ChunkingType::Parallel { hoisted, .. } => *hoisted, + // _ => unreachable!(), + // }, + // ) + // }); + // let module = node.module; + + // if ResolvedVc::try_downcast::>(module).is_some() { + // let idx = if hoisted + // && parent_module.is_some_and(|p| { + // ResolvedVc::try_downcast::>(p).is_some() + // }) { + // // An eligible edge: MergeableModule ---hoisted---> MergeableModule + // // Reuse the parent's list to later add the child to it + // parent_module + // .and_then(|p| state.current_list_indices.get(&p).copied()) + // .unwrap_or_else(|| { + // let idx = state.lists.len(); + // state.lists.push(Default::default()); + // idx + // }) + // } else { + // // The module get its own list + // let idx = state.lists.len(); + // state.lists.push(Default::default()); + // idx + // }; + // state.current_list_indices.insert(module, idx); + // } + // Ok(GraphTraversalAction::Continue) + // }, + // |_parent_info, node, state| { + // // On the up traversal (which corresponds to execution order), add the module + // to // the lists it belongs to. + // let module = node.module; + // // TODO when is a module exposed? + // // let is_exposed = parent_info.is_none(); + + // if let Some(mergable_module) = + // ResolvedVc::try_downcast::>(module) + // { + // let idx = *state.current_list_indices.get(&module).unwrap(); + // let list = state.lists.get_mut(idx).unwrap(); + + // // We might visit the module multiple times, but only add it the first + // time // (which corresponds to when it executes). + // if list.insert(mergable_module) { + // lists_reverse_map.entry(mergable_module).or_default().push( + // ListOccurence { + // list: idx, + // entry: list.len(), + // }, + // ); + // } + // } + // }, + // ) + // .await?; + + // lists.extend(state.lists); } // Sort the reverse mappings by the index in the lists, so that we start with smaller indices to From 75bb253aa8279a7689d25fa64ccd4c5338666b45 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 09:42:01 +0200 Subject: [PATCH 12/59] MergedModules global bitmap --- .../src/module_graph/merged_modules.rs | 357 ++++++++---------- 1 file changed, 150 insertions(+), 207 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 00def53c0c00e..8898f9b37351a 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -1,4 +1,4 @@ -use std::{cmp::Ordering, collections::hash_map::Entry}; +use std::collections::hash_map::Entry; use anyhow::Result; use roaring::RoaringBitmap; @@ -57,234 +57,170 @@ impl MergedModuleInfo { /// - if a merged module has an incoming edge not contained in the group, it has to expose its /// exports into the module cache. pub async fn compute_merged_modules(module_graph: Vc) -> Result> { - let chunk_groups = module_graph.chunk_group_info().await?; let module_graph = module_graph.await?; - #[allow(clippy::type_complexity)] - let mut replacements: FxHashMap< - ResolvedVc>, - ResolvedVc>, - > = Default::default(); - let mut included: FxHashSet>> = FxHashSet::default(); - - #[derive(Debug, PartialEq, Eq, Hash)] - struct ListOccurence { - list: usize, - entry: usize, - } - impl PartialOrd for ListOccurence { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - impl Ord for ListOccurence { - fn cmp(&self, other: &Self) -> Ordering { - self.entry.cmp(&other.entry) - } - } - - // A list of all different execution traces (orders) of all modules, initially one for each ESM - // subtree in the chunks, but futher split up later on. - let mut lists: Vec>>> = vec![]; - let mut lists_reverse_map: FxHashMap>, Vec> = - Default::default(); - - // Iterate over all chunk groups and collect all potentially mergeable modules (i.e. subtrees - // that are eligible for merging). - for chunk_group in &chunk_groups.chunk_groups { - // TODO parallelize the chunk_group loop - - let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = - FxHashMap::default(); - let mut next_index = 0u32; - - let visit_count = module_graph - .traverse_edges_fixed_point( - chunk_group.entries().map(|e| (e, 0)), - &mut module_merged_groups, - |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, - node: &'_ SingleModuleGraphModuleNode, - module_merged_groups: &mut FxHashMap< - ResolvedVc>, - RoaringBitmapWrapper, - >| - -> GraphTraversalAction { - // On the down traversal, establish which edges are mergable and set the list - // indices. - - if parent_info.is_some_and(|p| !p.1.is_parallel()) { - // We are only interested in this particular chunk group - return GraphTraversalAction::Exclude; - } - let (parent, hoisted) = parent_info.map_or((None, false), |(node, ty)| { - ( - Some(node.module), - match ty { - ChunkingType::Parallel { hoisted, .. } => *hoisted, - _ => unreachable!(), - }, - ) - }); - let module = node.module; - - if let (Some(parent_module), true) = (parent, hoisted) { - // Mergable with parent, inherit from parent - if parent_module == node.module { - // A self-reference - GraphTraversalAction::Skip + // Use all entries from all graphs + let graphs = module_graph.get_graphs().await?; + let entries = graphs + .iter() + .flat_map(|g| g.entries.iter()) + .flat_map(|g| g.entries()) + .collect::>(); + + let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = + FxHashMap::default(); + let mut next_index = 0u32; + + let visit_count = module_graph + .traverse_edges_fixed_point_with_priority( + entries.iter().map(|e| (*e, 0)), + &mut module_merged_groups, + |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, + node: &'_ SingleModuleGraphModuleNode, + module_merged_groups: &mut FxHashMap< + ResolvedVc>, + RoaringBitmapWrapper, + >| + -> GraphTraversalAction { + // On the down traversal, establish which edges are mergable and set the list + // indices. + let (parent_module, hoisted) = parent_info.map_or((None, false), |(node, ty)| { + ( + Some(node.module), + match ty { + ChunkingType::Parallel { hoisted, .. } => *hoisted, + _ => false, + }, + ) + }); + let module = node.module; + + if let (Some(parent_module), true, true) = ( + parent_module.filter(|m| { + ResolvedVc::try_downcast::>(*m).is_some() + }), + ResolvedVc::try_downcast::>(module).is_some(), + hoisted, + ) { + // A hoisted reference from a mergeable module to a mergeable module, inherit + // bitmaps from parent. + if parent_module == module { + // A self-reference + GraphTraversalAction::Skip + } else { + module_merged_groups.entry(node.module).or_default(); + let [Some(parent_merged_groups), Some(current_merged_groups)] = + module_merged_groups.get_disjoint_mut([ + &ResolvedVc::upcast(parent_module), + &node.module, + ]) + else { + // All modules are inserted in the previous iteration + unreachable!() + }; + + if current_merged_groups.is_empty() { + // Initial visit, clone instead of merging + *current_merged_groups = parent_merged_groups.clone(); + GraphTraversalAction::Continue + } else if parent_merged_groups.is_proper_superset(current_merged_groups) { + // Add bits from parent, and continue traversal because changed + **current_merged_groups |= &**parent_merged_groups; + GraphTraversalAction::Continue } else { - module_merged_groups.entry(node.module).or_default(); - let [Some(parent_merged_groups), Some(current_merged_groups)] = - module_merged_groups - .get_disjoint_mut([&parent_module, &node.module]) - else { - // All modules are inserted in the previous iteration - unreachable!() - }; - - if current_merged_groups.is_empty() { - // Initial visit, clone instead of merging - *current_merged_groups = parent_merged_groups.clone(); - GraphTraversalAction::Continue - } else if parent_merged_groups.is_proper_superset(current_merged_groups) - { - // Add bits from parent, and continue traversal because changed - **current_merged_groups |= &**parent_merged_groups; + // Unchanged, no need to forward to children + GraphTraversalAction::Skip + } + } + } else { + // Either a non-hoisted reference or an incompatible parent or child module, + // create a new group. + let idx = next_index; + next_index += 1; + + match module_merged_groups.entry(module) { + Entry::Occupied(mut entry) => { + let current = entry.get_mut(); + if !current.contains(idx) { + // Mark and continue traversal because modified + current.insert(idx); GraphTraversalAction::Continue } else { // Unchanged, no need to forward to children GraphTraversalAction::Skip } } - } else { - // Either a non-hoisted reference, or an incompatible parent, create a new - // group - let idx = next_index; - next_index += 1; - - match module_merged_groups.entry(module) { - Entry::Occupied(mut entry) => { - let current = entry.get_mut(); - if !current.contains(idx) { - // Mark and continue traversal because modified - current.insert(idx); - GraphTraversalAction::Continue - } else { - // Unchanged, no need to forward to children - GraphTraversalAction::Skip - } - } - Entry::Vacant(entry) => { - // First visit - entry.insert(RoaringBitmapWrapper( - RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), - )); - GraphTraversalAction::Continue - } + Entry::Vacant(entry) => { + // First visit + entry.insert(RoaringBitmapWrapper( + RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), + )); + GraphTraversalAction::Continue } } - }, - |_, _| 0, - ) - .await?; + } + }, + |_, _| 0, + ) + .await?; - let mut foo: FxIndexMap>> = Default::default(); + { + let mut x: FxIndexMap>> = Default::default(); for (k, v) in &module_merged_groups { - foo.entry(v.clone()) + x.entry(v.clone()) .or_default() .push(k.ident().to_string().await?); } - println!("{} {} {:#?}", visit_count, module_merged_groups.len(), foo); - - // module_graph - // .traverse_edges_from_entries_topological( - // chunk_group.entries(), - // &mut state, - // |parent_info, node, state| { - // // On the down traversal, establish which edges are mergable and set the list - // // indices. - // if parent_info.is_some_and(|p| !p.1.is_parallel()) { - // return Ok(GraphTraversalAction::Exclude); - // } - // let (parent_module, hoisted) = - // parent_info.map_or((None, false), |(node, ty)| { - // ( - // Some(node.module), - // match ty { - // ChunkingType::Parallel { hoisted, .. } => *hoisted, - // _ => unreachable!(), - // }, - // ) - // }); - // let module = node.module; - - // if ResolvedVc::try_downcast::>(module).is_some() { - // let idx = if hoisted - // && parent_module.is_some_and(|p| { - // ResolvedVc::try_downcast::>(p).is_some() - // }) { - // // An eligible edge: MergeableModule ---hoisted---> MergeableModule - // // Reuse the parent's list to later add the child to it - // parent_module - // .and_then(|p| state.current_list_indices.get(&p).copied()) - // .unwrap_or_else(|| { - // let idx = state.lists.len(); - // state.lists.push(Default::default()); - // idx - // }) - // } else { - // // The module get its own list - // let idx = state.lists.len(); - // state.lists.push(Default::default()); - // idx - // }; - // state.current_list_indices.insert(module, idx); - // } - // Ok(GraphTraversalAction::Continue) - // }, - // |_parent_info, node, state| { - // // On the up traversal (which corresponds to execution order), add the module - // to // the lists it belongs to. - // let module = node.module; - // // TODO when is a module exposed? - // // let is_exposed = parent_info.is_none(); - - // if let Some(mergable_module) = - // ResolvedVc::try_downcast::>(module) - // { - // let idx = *state.current_list_indices.get(&module).unwrap(); - // let list = state.lists.get_mut(idx).unwrap(); - - // // We might visit the module multiple times, but only add it the first - // time // (which corresponds to when it executes). - // if list.insert(mergable_module) { - // lists_reverse_map.entry(mergable_module).or_default().push( - // ListOccurence { - // list: idx, - // entry: list.len(), - // }, - // ); - // } - // } - // }, - // ) - // .await?; - - // lists.extend(state.lists); + println!( + "{} {} {:#?}", + visit_count, + module_merged_groups.len(), + x.iter().filter(|(_, v)| v.len() > 1).collect::>() + ); } - // Sort the reverse mappings by the index in the lists, so that we start with smaller indices to - // find larger common sequences - for list in lists_reverse_map.values_mut() { - list.sort_unstable(); - } + // A list of all different execution traces (orders) of all modules, initially one for each ESM + // subtree in the chunks, but futher split up later on. + let mut lists: FxIndexMap< + RoaringBitmapWrapper, + FxIndexSet>>, + > = FxIndexMap::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + + module_graph + .traverse_edges_from_entries_topological( + entries, + &mut (), + |_, _, _| Ok(GraphTraversalAction::Continue), + |_, node, _| { + let module = node.module; + if let Some(mergeable_module) = + ResolvedVc::try_downcast::>(module) + { + let bitmap = module_merged_groups + .get(&module) + .expect("Module should be in the map"); + lists + .entry(bitmap.clone()) + .or_default() + .insert(mergeable_module); + } + }, + ) + .await?; - // Split up lists to ensure each module only appears once in a list. - // TODO + println!( + "lists {:#?}", + lists + .iter() + .filter(|(_, v)| v.len() > 1) + .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + .try_join() + .await? + ); // Call MergeableModule impl to merge the modules (or not, if they are rejected). let result = lists - .into_iter() + .into_values() .map(async |list| { let mut resulting_list = vec![]; let mut included: Vec>> = vec![]; @@ -325,6 +261,13 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>, + ResolvedVc>, + > = Default::default(); + let mut included: FxHashSet>> = FxHashSet::default(); + for (replacements_part, included_part) in result.into_iter().flatten() { replacements.extend(replacements_part.into_iter()); included.extend(included_part); From fb5e2b278c4866fcfab2a8f4dd452cf1e29ebcbc Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 10:34:51 +0200 Subject: [PATCH 13/59] Don't merge CJS exports --- .../crates/turbopack-ecmascript/src/lib.rs | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 07f966e96ac58..bee7603d3a143 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -703,8 +703,6 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleAsset { #[turbo_tasks::value_impl] impl MergeableModule for EcmascriptModuleAsset { - // Clippy is wrong here, they are not equivalent (the for-loop restarts the iterator) - #[allow(clippy::while_let_on_iterator)] #[turbo_tasks::function] async fn merge( self: ResolvedVc, @@ -719,10 +717,34 @@ impl MergeableModule for EcmascriptModuleAsset { while let Some(m) = modules.next() { // Skip some modules, try to find the first eligible module if let Some(m) = ResolvedVc::try_sidecast::>(*m) { + if let Some(placeable) = + ResolvedVc::try_sidecast::>(m) + { + if matches!( + &*placeable.get_exports().await?, + |EcmascriptExports::DynamicNamespace| EcmascriptExports::CommonJs + | EcmascriptExports::EmptyCommonJs + | EcmascriptExports::Value + ) { + continue; + } + } consumed_modules.push(m); - // Consume as many as possible to merge together - while let Some(m) = modules.next() { + // Consume as many modules as possible to merge together + for m in &mut modules { if let Some(m) = ResolvedVc::try_sidecast::>(*m) { + if let Some(placeable) = + ResolvedVc::try_sidecast::>(m) + { + if matches!( + &*placeable.get_exports().await?, + |EcmascriptExports::DynamicNamespace| EcmascriptExports::CommonJs + | EcmascriptExports::EmptyCommonJs + | EcmascriptExports::Value + ) { + break; + } + } consumed_modules.push(m); } else { break; From b4d9db4620dec05aefe7cbb80d0ac755728c528c Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 11:04:41 +0200 Subject: [PATCH 14/59] MergedModules --- .../src/module_graph/merged_modules.rs | 451 +++++++++--------- .../turbopack-core/src/module_graph/mod.rs | 2 +- 2 files changed, 224 insertions(+), 229 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 8898f9b37351a..f475b1bc746ce 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -3,6 +3,7 @@ use std::collections::hash_map::Entry; use anyhow::Result; use roaring::RoaringBitmap; use rustc_hash::{FxHashMap, FxHashSet}; +use tracing::Instrument; use turbo_tasks::{ FxIndexMap, FxIndexSet, ReadRef, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc, }; @@ -56,260 +57,254 @@ impl MergedModuleInfo { /// treated as one. /// - if a merged module has an incoming edge not contained in the group, it has to expose its /// exports into the module cache. -pub async fn compute_merged_modules(module_graph: Vc) -> Result> { - let module_graph = module_graph.await?; +pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result> { + let span_outer = tracing::info_span!( + "compute merged modules", + module_count = tracing::field::Empty, + visit_count = tracing::field::Empty, + merged_groups = tracing::field::Empty, + included_modules = tracing::field::Empty + ); - // Use all entries from all graphs - let graphs = module_graph.get_graphs().await?; - let entries = graphs - .iter() - .flat_map(|g| g.entries.iter()) - .flat_map(|g| g.entries()) - .collect::>(); + let span = span_outer.clone(); + async move { + let graphs = module_graph.graphs.iter().try_join().await?; + let module_count = graphs.iter().map(|g| g.graph.node_count()).sum::(); + span.record("module_count", module_count); - let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = - FxHashMap::default(); - let mut next_index = 0u32; + // Use all entries from all graphs + let entries = graphs + .iter() + .flat_map(|g| g.entries.iter()) + .flat_map(|g| g.entries()) + .collect::>(); - let visit_count = module_graph - .traverse_edges_fixed_point_with_priority( - entries.iter().map(|e| (*e, 0)), - &mut module_merged_groups, - |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, - node: &'_ SingleModuleGraphModuleNode, - module_merged_groups: &mut FxHashMap< - ResolvedVc>, - RoaringBitmapWrapper, - >| - -> GraphTraversalAction { - // On the down traversal, establish which edges are mergable and set the list - // indices. - let (parent_module, hoisted) = parent_info.map_or((None, false), |(node, ty)| { - ( - Some(node.module), - match ty { - ChunkingType::Parallel { hoisted, .. } => *hoisted, - _ => false, - }, - ) - }); - let module = node.module; + let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = + FxHashMap::default(); + let mut next_index = 0u32; - if let (Some(parent_module), true, true) = ( - parent_module.filter(|m| { - ResolvedVc::try_downcast::>(*m).is_some() - }), - ResolvedVc::try_downcast::>(module).is_some(), - hoisted, - ) { - // A hoisted reference from a mergeable module to a mergeable module, inherit - // bitmaps from parent. - if parent_module == module { - // A self-reference - GraphTraversalAction::Skip - } else { - module_merged_groups.entry(node.module).or_default(); - let [Some(parent_merged_groups), Some(current_merged_groups)] = - module_merged_groups.get_disjoint_mut([ - &ResolvedVc::upcast(parent_module), - &node.module, - ]) - else { - // All modules are inserted in the previous iteration - unreachable!() - }; + let visit_count = module_graph + .traverse_edges_fixed_point_with_priority( + entries.iter().map(|e| (*e, 0)), + &mut module_merged_groups, + |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, + node: &'_ SingleModuleGraphModuleNode, + module_merged_groups: &mut FxHashMap< + ResolvedVc>, + RoaringBitmapWrapper, + >| + -> Result { + // On the down traversal, establish which edges are mergable and set the list + // indices. + let (parent_module, hoisted) = + parent_info.map_or((None, false), |(node, ty)| { + ( + Some(node.module), + match ty { + ChunkingType::Parallel { hoisted, .. } => *hoisted, + _ => false, + }, + ) + }); + let module = node.module; - if current_merged_groups.is_empty() { - // Initial visit, clone instead of merging - *current_merged_groups = parent_merged_groups.clone(); - GraphTraversalAction::Continue - } else if parent_merged_groups.is_proper_superset(current_merged_groups) { - // Add bits from parent, and continue traversal because changed - **current_merged_groups |= &**parent_merged_groups; - GraphTraversalAction::Continue - } else { - // Unchanged, no need to forward to children + if let (Some(parent_module), true, true) = ( + parent_module.filter(|m| { + ResolvedVc::try_downcast::>(*m).is_some() + }), + ResolvedVc::try_downcast::>(module).is_some(), + hoisted, + ) { + // A hoisted reference from a mergeable module to a mergeable module, + // inherit bitmaps from parent. + if parent_module == module { + // A self-reference GraphTraversalAction::Skip - } - } - } else { - // Either a non-hoisted reference or an incompatible parent or child module, - // create a new group. - let idx = next_index; - next_index += 1; + } else { + module_merged_groups.entry(node.module).or_default(); + let [Some(parent_merged_groups), Some(current_merged_groups)] = + module_merged_groups.get_disjoint_mut([ + &ResolvedVc::upcast(parent_module), + &node.module, + ]) + else { + // All modules are inserted in the previous iteration + unreachable!() + }; - match module_merged_groups.entry(module) { - Entry::Occupied(mut entry) => { - let current = entry.get_mut(); - if !current.contains(idx) { - // Mark and continue traversal because modified - current.insert(idx); + if current_merged_groups.is_empty() { + // Initial visit, clone instead of merging + *current_merged_groups = parent_merged_groups.clone(); + GraphTraversalAction::Continue + } else if parent_merged_groups.is_proper_superset(current_merged_groups) + { + // Add bits from parent, and continue traversal because changed + **current_merged_groups |= &**parent_merged_groups; GraphTraversalAction::Continue } else { // Unchanged, no need to forward to children GraphTraversalAction::Skip } } - Entry::Vacant(entry) => { - // First visit - entry.insert(RoaringBitmapWrapper( - RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), - )); - GraphTraversalAction::Continue + } else { + // Either a non-hoisted reference or an incompatible parent or child module, + // create a new group. + let idx = next_index; + next_index += 1; + + match module_merged_groups.entry(module) { + Entry::Occupied(mut entry) => { + let current = entry.get_mut(); + if !current.contains(idx) { + // Mark and continue traversal because modified + current.insert(idx); + GraphTraversalAction::Continue + } else { + // Unchanged, no need to forward to children + GraphTraversalAction::Skip + } + } + Entry::Vacant(entry) => { + // First visit + entry.insert(RoaringBitmapWrapper( + RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), + )); + GraphTraversalAction::Continue + } } - } - } - }, - |_, _| 0, - ) - .await?; + }) + }, + |_, _| Ok(0), + ) + .await?; - { - let mut x: FxIndexMap>> = Default::default(); - for (k, v) in &module_merged_groups { - x.entry(v.clone()) - .or_default() - .push(k.ident().to_string().await?); - } - println!( - "{} {} {:#?}", - visit_count, - module_merged_groups.len(), - x.iter().filter(|(_, v)| v.len() > 1).collect::>() - ); - } + span.record("visit_count", visit_count); - // A list of all different execution traces (orders) of all modules, initially one for each ESM - // subtree in the chunks, but futher split up later on. - let mut lists: FxIndexMap< - RoaringBitmapWrapper, - FxIndexSet>>, - > = FxIndexMap::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + // { + // let mut x: FxIndexMap>> = + // Default::default(); for (k, v) in &module_merged_groups { + // x.entry(v.clone()) + // .or_default() + // .push(k.ident().to_string().await?); + // } + // println!( + // "list candidates {} {} {:#?}", + // visit_count, + // module_merged_groups.len(), + // x.iter().filter(|(_, v)| v.len() > 1).collect::>() + // ); + // } - module_graph - .traverse_edges_from_entries_topological( - entries, - &mut (), - |_, _, _| Ok(GraphTraversalAction::Continue), - |_, node, _| { - let module = node.module; - if let Some(mergeable_module) = - ResolvedVc::try_downcast::>(module) - { - let bitmap = module_merged_groups - .get(&module) - .expect("Module should be in the map"); - lists - .entry(bitmap.clone()) - .or_default() - .insert(mergeable_module); - } - }, - ) - .await?; + // A list of all different execution traces (orders) of all modules, initially one for each + // ESM subtree in the chunks, but futher split up later on. + let mut lists: FxIndexMap< + RoaringBitmapWrapper, + FxIndexSet>>, + > = FxIndexMap::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); - println!( - "lists {:#?}", - lists - .iter() - .filter(|(_, v)| v.len() > 1) - .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) - .try_join() - .await? - ); + module_graph + .traverse_edges_from_entries_topological( + entries, + &mut (), + |_, _, _| Ok(GraphTraversalAction::Continue), + |_, node, _| { + let module = node.module; + if let Some(mergeable_module) = + ResolvedVc::try_downcast::>(module) + { + let bitmap = module_merged_groups + .get(&module) + .expect("Module should be in the map"); + lists + .entry(bitmap.clone()) + .or_default() + .insert(mergeable_module); + } + }, + ) + .await?; - // Call MergeableModule impl to merge the modules (or not, if they are rejected). - let result = lists - .into_values() - .map(async |list| { - let mut resulting_list = vec![]; - let mut included: Vec>> = vec![]; + // println!( + // "lists {:#?}", + // lists + // .iter() + // .filter(|(_, v)| v.len() > 1) + // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // .try_join() + // .await? + // ); - let mut i = 0; - while i < list.len() - 1 { - let first = *list.iter().nth(i).unwrap(); - let modules = list.iter().skip(i).map(|m| **m).collect::>(); - match *first.merge(MergeableModules::interned(modules)).await? { - MergeableModuleResult::Merged { - merged_module, - consumed, - skipped, - } => { - resulting_list - .push((ResolvedVc::upcast::>(first), merged_module)); - included.extend( - list.iter() - .skip(i) - .skip(skipped as usize) - // The first module should not be `included` but `replaced` - .skip(1) - .take(consumed as usize) - .copied() - .map(ResolvedVc::upcast), - ); - i += (skipped + consumed) as usize; - } - MergeableModuleResult::NotMerged => { - // None of them are mergeable. - return Ok(None); - } + // Call MergeableModule impl to merge the modules (or not, if they are rejected). + let result = lists + .into_values() + .map(async |list| { + if list.len() < 2 { + // Nothing to merge + return Ok(None); } - } - Ok(Some((resulting_list, included))) - }) - .try_join() - .await?; + let mut resulting_list = vec![]; + let mut included: Vec>> = vec![]; - #[allow(clippy::type_complexity)] - let mut replacements: FxHashMap< - ResolvedVc>, - ResolvedVc>, - > = Default::default(); - let mut included: FxHashSet>> = FxHashSet::default(); + let mut i = 0; + while i < list.len() - 1 { + let first = *list.iter().nth(i).unwrap(); + let modules = list.iter().skip(i).map(|m| **m).collect::>(); + match *first.merge(MergeableModules::interned(modules)).await? { + MergeableModuleResult::Merged { + merged_module, + consumed, + skipped, + } => { + resulting_list.push(( + ResolvedVc::upcast::>(first), + merged_module, + )); + included.extend( + list.iter() + .skip(i) + .skip(skipped as usize) + // The first module should not be `included` but `replaced` + .skip(1) + .take(consumed as usize) + .copied() + .map(ResolvedVc::upcast), + ); + i += (skipped + consumed) as usize; + } + MergeableModuleResult::NotMerged => { + // None of them are mergeable. + return Ok(None); + } + } + } - for (replacements_part, included_part) in result.into_iter().flatten() { - replacements.extend(replacements_part.into_iter()); - included.extend(included_part); - } + Ok(Some((resulting_list, included))) + }) + .try_join() + .await?; - // println!( - // "lists {:#?}", - // lists - // .iter() - // .map(|m| m.iter().map(|m| m.ident().to_string()).try_join()) - // .try_join() - // .await? - // ); - // println!( - // "lists_reverse_map {:#?}", - // lists_reverse_map - // .iter() - // .map(async |(k, v)| Ok((k.ident().to_string().await?, v))) - // .try_join() - // .await? - // ); + #[allow(clippy::type_complexity)] + let mut replacements: FxHashMap< + ResolvedVc>, + ResolvedVc>, + > = Default::default(); + let mut included: FxHashSet>> = FxHashSet::default(); - println!( - "included {:#?}", - included - .iter() - .map(|m| m.ident().to_string()) - .try_join() - .await? - ); - println!( - "replacements {:#?}", - replacements - .iter() - .map(async |(k, v)| Ok((k.ident().to_string().await?, v.ident().to_string().await?))) - .try_join() - .await? - ); + for (replacements_part, included_part) in result.into_iter().flatten() { + replacements.extend(replacements_part.into_iter()); + included.extend(included_part); + } - Ok(MergedModuleInfo { - replacements, - included, + span.record("merged_groups", replacements.len()); + span.record("included_modules", included.len()); + + Ok(MergedModuleInfo { + replacements, + included, + } + .cell()) } - .cell()) + .instrument(span_outer) + .await } diff --git a/turbopack/crates/turbopack-core/src/module_graph/mod.rs b/turbopack/crates/turbopack-core/src/module_graph/mod.rs index 4c80eab459064..740d5194e2d4e 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/mod.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/mod.rs @@ -761,7 +761,7 @@ impl ModuleGraph { } #[turbo_tasks::function] - pub async fn merged_modules(self: Vc) -> Result> { + pub async fn merged_modules(&self) -> Result> { compute_merged_modules(self).await } From 63430517bb4043b6c8f962d27bd1b49b7e83246d Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 14:17:45 +0200 Subject: [PATCH 15/59] fixups --- .../src/module_graph/merged_modules.rs | 74 ++++++++++++--- .../crates/turbopack-ecmascript/src/lib.rs | 92 ++++++++++++------- .../turbopack-ecmascript/src/merged_module.rs | 16 ++-- 3 files changed, 129 insertions(+), 53 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index f475b1bc746ce..00b5124c92c3a 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -248,28 +248,58 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result>(); + let first = list[i]; + let modules = list[i..].iter().map(|m| **m).collect::>(); match *first.merge(MergeableModules::interned(modules)).await? { MergeableModuleResult::Merged { merged_module, consumed, skipped, } => { + // println!( + // "accepted from {:?} {:#?} {:?} consumed {} {:#?} skipped {} + // {:#?}", first.ident().to_string(). + // await?, list[i..] + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // merged_module.ident().to_string().await?, + // consumed, + // list.iter() + // .skip(i) + // .skip(skipped as usize) + // .take(consumed as usize) + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // skipped, + // list.iter() + // .skip(i) + // .take(skipped as usize) + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // ); + + let mut current_included = list[i..] + .iter() + .skip(skipped as usize) + .take(consumed as usize); + // The first module should not be `included` but `replaced` + let first = *current_included.next().unwrap(); + debug_assert!( + first.ident().to_string().await? + == merged_module.ident().to_string().await?, + "{} == {}", + first.ident().to_string().await?, + merged_module.ident().to_string().await? + ); resulting_list.push(( ResolvedVc::upcast::>(first), merged_module, )); - included.extend( - list.iter() - .skip(i) - .skip(skipped as usize) - // The first module should not be `included` but `replaced` - .skip(1) - .take(consumed as usize) - .copied() - .map(ResolvedVc::upcast), - ); + included.extend(current_included.copied().map(ResolvedVc::upcast)); i += (skipped + consumed) as usize; } MergeableModuleResult::NotMerged => { @@ -299,6 +329,26 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result, ) -> Result> { let modules = modules.await?; - let mut modules = modules.iter(); - let mut skipped = 0; - let mut consumed_modules = vec![]; + let mut skipped = 0u32; - while let Some(m) = modules.next() { - // Skip some modules, try to find the first eligible module - if let Some(m) = ResolvedVc::try_sidecast::>(*m) { + async fn is_eligible( + module: ResolvedVc>, + ) -> Result>>> { + if let Some(analyzable) = + ResolvedVc::try_sidecast::>(module) + { if let Some(placeable) = - ResolvedVc::try_sidecast::>(m) + ResolvedVc::try_sidecast::>(module) { if matches!( &*placeable.get_exports().await?, @@ -726,51 +727,76 @@ impl MergeableModule for EcmascriptModuleAsset { | EcmascriptExports::EmptyCommonJs | EcmascriptExports::Value ) { - continue; + return Ok(None); } } - consumed_modules.push(m); + Ok(Some(analyzable)) + } else { + Ok(None) + } + } + + // let mut start_idx = None; + // let mut length = 0; + // for i in 0..modules.len() { + // let module = modules[i]; + // if let Some(module) = is_eligible(module).await? { + // if start_idx.is_some() { + // continue; + // } else { + // start_idx = Some(i); + // } + // } else { + // if let Some(start_idx) = start_idx + // && (i - start_idx) >= 2 + // { + // // We found a sequence of modules containing least 2 modules + // length = i - start_idx; + // break; + // } else { + // start_idx = None; + // } + // } + // } + // let Some(start_idx) = start_idx else { + // return Ok(MergeableModuleResult::not_merged()); + // }; + // let consumed_modules = modules[start_idx..start_idx + length].to_vec(); + + let mut modules = modules.iter(); + let mut merged_modules = vec![]; + while let Some(first) = modules.next() { + // Skip some modules, try to find the first eligible module + if let Some(first) = is_eligible(*first).await? { + merged_modules.push(first); // Consume as many modules as possible to merge together for m in &mut modules { - if let Some(m) = ResolvedVc::try_sidecast::>(*m) { - if let Some(placeable) = - ResolvedVc::try_sidecast::>(m) - { - if matches!( - &*placeable.get_exports().await?, - |EcmascriptExports::DynamicNamespace| EcmascriptExports::CommonJs - | EcmascriptExports::EmptyCommonJs - | EcmascriptExports::Value - ) { - break; - } - } - consumed_modules.push(m); + if let Some(m) = is_eligible(*m).await? { + merged_modules.push(m); } else { + skipped += 1 + (merged_modules.len() as u32); break; } } - if consumed_modules.len() > 1 { - // Successfully found something to + if merged_modules.len() > 1 { + // Successfully found something to merge break; } else { - // Only a single module, ignore this one and try to find a bigger sequence in - // the remaining list. - consumed_modules.clear(); - skipped += 1; + // Only a single module, ignore this one and try to find a bigger + // sequence in the remaining list. + merged_modules.clear(); } } else { skipped += 1; } } - if !consumed_modules.is_empty() { - #[allow(unreachable_code)] + if !merged_modules.is_empty() { Ok(MergeableModuleResult::Merged { - consumed: consumed_modules.len() as u32, + consumed: merged_modules.len() as u32, skipped, merged_module: ResolvedVc::upcast(MergedEcmascriptModule::new( - consumed_modules, + merged_modules, // TODO where to get options from? self.options().to_resolved().await?, )), diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs index b2685bfc98a36..f1ce475d584af 100644 --- a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -122,14 +122,14 @@ impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { ) -> Result> { let module = self.module.await?; let modules = &module.modules; - println!( - "merged chunk item: {:?}", - modules - .iter() - .map(|m| m.ident().to_string()) - .try_join() - .await? - ); + // println!( + // "merged chunk item: {:?}", + // modules + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await? + // ); let options = modules .iter() .map(|m| { From 13e482def46362b2d59503848d6d227d3579179c Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 22:17:52 +0200 Subject: [PATCH 16/59] fixup codegen --- .../crates/turbopack-ecmascript/src/lib.rs | 54 +++--- .../src/references/async_module.rs | 15 +- .../src/references/esm/base.rs | 179 ++++++++++++++++-- .../src/references/esm/binding.rs | 179 +++--------------- .../src/references/esm/export.rs | 65 +++---- .../src/side_effect_optimization/reference.rs | 12 +- 6 files changed, 262 insertions(+), 242 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index abb7fbeb4f7a8..775ec3f52f14f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -1137,22 +1137,31 @@ impl EcmascriptModuleContent { } else { unreachable!() }; - let (is_export_mark, module_marks) = GLOBALS.set(globals, || { - ( - Mark::new(), - FxIndexMap::from_iter(modules.keys().map(|m| (*m, Mark::new()))), - ) + let (is_export_mark, module_syntax_contexts) = GLOBALS.set(globals, || { + let is_export_mark = Mark::new(); + let module_syntax_contexts: FxIndexMap<_, _> = modules + .keys() + .map(|m| { + let mark = Mark::fresh(is_export_mark); + ( + *m, + SyntaxContext::empty() + .apply_mark(is_export_mark) + .apply_mark(mark), + ) + }) + .collect(); + (is_export_mark, module_syntax_contexts) }); let ctx = ScopeHoistingContext { module, modules: &modules, - is_export_mark, - module_marks: &module_marks, + module_syntax_contexts: &module_syntax_contexts, }; let code_gens = options.merged_code_gens(Some(ctx)).await?; Ok(( module, - module_marks, + module_syntax_contexts, is_export_mark, process_parse_result( *parsed, @@ -1172,30 +1181,24 @@ impl EcmascriptModuleContent { struct SetSyntaxContextVisitor<'a> { current_module: ResolvedVc>, - // A marker to identify the special cross-module variable references + // A marker to quickly identify the special cross-module variable references export_mark: Mark, // The syntax contexts in the merged AST (each module has its own) merged_ctxts: &'a FxIndexMap>, SyntaxContext>, - // The export marks in the current AST, which will be mapped to merged_ctxts - current_module_marks: - &'a FxIndexMap>, Mark>, + // The export syntax contexts in the current AST, which will be mapped to merged_ctxts + current_module_contexts: + &'a FxIndexMap>, SyntaxContext>, } impl VisitMut for SetSyntaxContextVisitor<'_> { fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { let module = if ctxt.has_mark(self.export_mark) { *self - .current_module_marks + .current_module_contexts .iter() - .filter_map(|(module, mark)| { - if ctxt.has_mark(*mark) { - Some(module) - } else { - None - } - }) - .next() + .find(|(_, module_ctxt)| *ctxt == **module_ctxt) .unwrap() + .0 } else { self.current_module }; @@ -1213,7 +1216,7 @@ impl EcmascriptModuleContent { shebang: None, body: contents .into_iter() - .flat_map(|(module, module_marks, export_mark, content)| { + .flat_map(|(module, module_contexts, export_mark, content)| { if let CodeGenResult { program: Program::Module(mut content), globals, @@ -1225,7 +1228,7 @@ impl EcmascriptModuleContent { current_module: module, export_mark, merged_ctxts: &merged_ctxts, - current_module_marks: &module_marks, + current_module_contexts: &module_contexts, }); }); @@ -1285,8 +1288,9 @@ impl EcmascriptModuleContent { pub struct ScopeHoistingContext<'a> { module: ResolvedVc>, modules: &'a FxIndexMap>, bool>, - is_export_mark: Mark, - module_marks: &'a FxIndexMap>, Mark>, + /// To import a specifier from another module, apply this context to the Ident + module_syntax_contexts: + &'a FxIndexMap>, SyntaxContext>, } struct CodeGenResult { diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index 75a731a5f9183..fbf8739e85204 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -16,7 +16,10 @@ use turbopack_core::{ }; use super::esm::base::ReferencedAsset; -use crate::code_gen::{CodeGeneration, CodeGenerationHoistedStmt}; +use crate::{ + code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, + references::esm::base::ReferencedAssetIdent, +}; /// Information needed for generating the async module wrapper for /// [EcmascriptChunkItem](crate::chunk::EcmascriptChunkItem)s. @@ -122,7 +125,10 @@ impl AsyncModule { Ok(match &*referenced_asset { ReferencedAsset::External(_, ExternalType::EcmaScriptModule) => { if self.import_externals { - referenced_asset.get_ident(chunking_context).await? + referenced_asset + .get_ident(chunking_context, None, None) + .await? + .map(|i| i.into_module_namespace_ident().unwrap()) } else { None } @@ -132,7 +138,10 @@ impl AsyncModule { .referenced_async_modules .contains(&ResolvedVc::upcast(*placeable)) { - referenced_asset.get_ident(chunking_context).await? + referenced_asset + .get_ident(chunking_context, None, None) + .await? + .map(|i| i.into_module_namespace_ident().unwrap()) } else { None } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 8d96aa25dffc6..ca786b6554da7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -1,8 +1,12 @@ use anyhow::{Result, anyhow, bail}; +use either::Either; use strsim::jaro; use swc_core::{ - common::{BytePos, DUMMY_SP, Span}, - ecma::ast::{Decl, Expr, ExprStmt, Ident, Stmt}, + common::{BytePos, DUMMY_SP, Mark, Span, SyntaxContext}, + ecma::ast::{ + ComputedPropName, Decl, Expr, ExprStmt, Ident, Lit, MemberExpr, MemberProp, Number, + SeqExpr, Stmt, Str, + }, quote, }; use turbo_rcstr::RcStr; @@ -34,10 +38,13 @@ use super::export::{all_known_export_names, is_export_missing}; use crate::{ ScopeHoistingContext, TreeShakingMode, analyzer::imports::ImportAnnotations, - chunk::EcmascriptChunkPlaceable, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::CodeGeneration, magic_identifier, - references::util::{request_to_string, throw_module_not_found_expr}, + references::{ + esm::EsmExport, + util::{request_to_string, throw_module_not_found_expr}, + }, runtime_functions::{TURBOPACK_EXTERNAL_IMPORT, TURBOPACK_EXTERNAL_REQUIRE, TURBOPACK_IMPORT}, tree_shake::{TURBOPACK_PART_IMPORT_SOURCE, asset::EcmascriptModulePartAsset}, utils::module_id_to_lit, @@ -51,18 +58,151 @@ pub enum ReferencedAsset { Unresolvable, } +pub enum ReferencedAssetIdent { + LocalBinding { + ident: RcStr, + ctxt: SyntaxContext, + }, + Module { + namespace_ident: String, + export: Option, + }, +} + +impl ReferencedAssetIdent { + pub fn into_module_namespace_ident(self) -> Option { + match self { + ReferencedAssetIdent::Module { + namespace_ident, .. + } => Some(namespace_ident), + ReferencedAssetIdent::LocalBinding { .. } => None, + } + } + + pub fn as_expr_individual(&self, span: Span) -> Either { + match self { + ReferencedAssetIdent::LocalBinding { ident, ctxt } => { + Either::Left(Ident::new(ident.as_str().into(), span, *ctxt)) + } + ReferencedAssetIdent::Module { + namespace_ident, + export, + } => { + if let Some(export) = export { + Either::Right(MemberExpr { + span, + obj: Box::new(Expr::Ident(Ident::new( + namespace_ident.as_str().into(), + span, + Default::default(), + ))), + prop: MemberProp::Computed(ComputedPropName { + span, + expr: Box::new(Expr::Lit(Lit::Str(Str { + span, + value: export.as_str().into(), + raw: None, + }))), + }), + }) + } else { + Either::Left(Ident::new( + namespace_ident.as_str().into(), + span, + Default::default(), + )) + } + } + } + } + pub fn as_expr(&self, span: Span, is_callee: bool) -> Expr { + match self.as_expr_individual(span) { + Either::Left(ident) => ident.into(), + Either::Right(member) => { + if is_callee { + Expr::Seq(SeqExpr { + exprs: vec![ + Box::new(Expr::Lit(Lit::Num(Number { + span, + value: 0.0, + raw: None, + }))), + Box::new(member.into()), + ], + span, + }) + } else { + member.into() + } + } + } + } +} + impl ReferencedAsset { pub async fn get_ident( &self, chunking_context: Vc>, - ) -> Result> { + export: Option, + scope_hoisting_context: Option>, + ) -> Result> { Ok(match self { ReferencedAsset::Some(asset) => { - Some(Self::get_ident_from_placeable(asset, chunking_context).await?) + if let Some(scope_hoisting_context) = scope_hoisting_context { + if let Some(ctxt) = scope_hoisting_context + .module_syntax_contexts + .get(&ResolvedVc::upcast(*asset)) + { + if let Some(export) = &export { + if let EcmascriptExports::EsmExports(exports) = + *asset.get_exports().await? + { + let exports = exports.await?; + let export = exports.exports.get(export); + match export { + Some(EsmExport::LocalBinding(name, _)) => { + // A local binding in a module that is merged in the same + // group + return Ok(Some(ReferencedAssetIdent::LocalBinding { + ident: name.clone(), + ctxt: *ctxt, + })); + } + Some(EsmExport::ImportedBinding(esm_ref, name, _)) => { + let referenced_asset = + ReferencedAsset::from_resolve_result( + esm_ref.resolve_reference(), + ) + .await?; + + // If the target module is still in the same group, we can + // refer it locally, otherwise it will be imported + return Box::pin(referenced_asset.get_ident( + chunking_context, + Some(name.clone()), + Some(scope_hoisting_context), + )) + .await; + } + _ => { + todo!("TODO {:?}", export) + } + } + } + } + } + } + + Some(ReferencedAssetIdent::Module { + namespace_ident: Self::get_ident_from_placeable(asset, chunking_context) + .await?, + export, + }) } - ReferencedAsset::External(request, ty) => Some(magic_identifier::mangle(&format!( - "{ty} external {request}" - ))), + ReferencedAsset::External(request, ty) => Some(ReferencedAssetIdent::Module { + namespace_ident: magic_identifier::mangle(&format!("{ty} external {request}")), + export, + }), ReferencedAsset::None | ReferencedAsset::Unresolvable => None, }) } @@ -321,7 +461,10 @@ impl EsmAssetReference { span: DUMMY_SP, }); Some((format!("throw {request}").into(), stmt)) - } else if let Some(ident) = referenced_asset.get_ident(chunking_context).await? { + } else if let Some(ident) = referenced_asset + .get_ident(chunking_context, None, scope_hoisting_context) + .await? + { let span = this .issue_source .to_swc_offsets() @@ -342,13 +485,13 @@ impl EsmAssetReference { None } else { let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; - let name = ident; + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); Some(( id.to_string().into(), var_decl_with_span( quote!( "var $name = $turbopack_import($id);" as Stmt, - name = Ident::new(name.clone().into(), DUMMY_SP, Default::default()), + name = name, turbopack_import: Expr = TURBOPACK_IMPORT.into(), id: Expr = module_id_to_lit(&id), ), @@ -370,20 +513,21 @@ impl EsmAssetReference { request ); } + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); Some(( - ident.clone().into(), + name.sym.as_str().into(), var_decl_with_span( if import_externals { quote!( "var $name = $turbopack_external_import($id);" as Stmt, - name = Ident::new(ident.clone().into(), DUMMY_SP, Default::default()), + name = name, turbopack_external_import: Expr = TURBOPACK_EXTERNAL_IMPORT.into(), id: Expr = Expr::Lit(request.clone().to_string().into()) ) } else { quote!( "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, - name = Ident::new(ident.clone().into(), DUMMY_SP, Default::default()), + name = name, turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), id: Expr = Expr::Lit(request.clone().to_string().into()) ) @@ -408,12 +552,13 @@ impl EsmAssetReference { request ); } + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); Some(( - ident.clone().into(), + name.sym.as_str().into(), var_decl_with_span( quote!( "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, - name = Ident::new(ident.clone().into(), DUMMY_SP, Default::default()), + name = name, turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), id: Expr = Expr::Lit(request.clone().to_string().into()) ), diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs index cdfb78cd008df..2c908b70d739d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -1,7 +1,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use swc_core::{ - common::{Mark, Span, SyntaxContext}, + common::{Span, SyntaxContext}, ecma::{ ast::{ ComputedPropName, Expr, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, Number, Prop, @@ -17,12 +17,11 @@ use turbopack_core::{chunk::ChunkingContext, module_graph::ModuleGraph}; use super::EsmAssetReference; use crate::{ ScopeHoistingContext, - chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGen, CodeGeneration}, create_visitor, references::{ AstPath, - esm::{EsmExport, base::ReferencedAsset}, + esm::base::{ReferencedAsset, ReferencedAssetIdent}, }, }; @@ -58,49 +57,15 @@ impl EsmBinding { let imported_module = self.reference.get_referenced_asset().await?; enum ImportedIdent { - Module(String), - Local(RcStr, [Mark; 2]), + Module(ReferencedAssetIdent), None, Unresolvable, } let imported_ident = match &*imported_module { ReferencedAsset::None => ImportedIdent::None, - ReferencedAsset::Some(module) => { - let mut result = None; - if let Some(scope_hoisting_context) = scope_hoisting_context { - if let Some(mark) = scope_hoisting_context - .module_marks - .get(&ResolvedVc::upcast(*module)) - { - if let Some(export) = &export { - if let EcmascriptExports::EsmExports(exports) = - *module.get_exports().await? - { - let exports = exports.await?; - let export = exports.exports.get(export); - if let Some(EsmExport::LocalBinding(name, _)) = export { - result = Some(ImportedIdent::Local( - name.clone(), - [*mark, scope_hoisting_context.is_export_mark], - )); - } else { - // TODO - } - } - } - } - } - if let Some(result) = result { - result - } else { - ImportedIdent::Module( - imported_module.get_ident(chunking_context).await?.unwrap(), - ) - } - } imported_module => imported_module - .get_ident(chunking_context) + .get_ident(chunking_context, export, scope_hoisting_context) .await? .map_or(ImportedIdent::Unresolvable, ImportedIdent::Module), }; @@ -120,35 +85,16 @@ impl EsmBinding { ImportedIdent::Module(imported_ident) => { *prop = Prop::KeyValue(KeyValueProp { key: PropName::Ident(ident.clone().into()), - value: Box::new(make_module_expr( - imported_ident, - export.as_deref(), - ident.span, - false, - )), + value: Box::new(imported_ident.as_expr(ident.span, false)) }); } ImportedIdent::None => { - *prop = Prop::KeyValue(KeyValueProp { key: PropName::Ident(ident.clone().into()), value: Expr::undefined(ident.span), }); } - ImportedIdent::Local(local_ident, marks) => { - *prop = Prop::KeyValue( - KeyValueProp { - key: PropName::Ident(ident.clone().into()), - value: Box::new(make_local_expr( - local_ident, - export.as_deref(), - ident.span, - *marks - ).into()), - } - ); - } ImportedIdent::Unresolvable => { // Do nothing, the reference will insert a throw } @@ -173,15 +119,7 @@ impl EsmBinding { use swc_core::common::Spanned; match &imported_ident { ImportedIdent::Module(imported_ident) => { - *expr = make_module_expr(imported_ident, export.as_deref(), expr.span(), in_call); - } - ImportedIdent::Local(local_ident, marks) => { - *expr = make_local_expr( - local_ident, - export.as_deref(), - expr.span(), - *marks - ).into(); + *expr = imported_ident.as_expr(expr.span(), in_call); } ImportedIdent::None => { *expr = *Expr::undefined(expr.span()); @@ -208,27 +146,27 @@ impl EsmBinding { ast_path.pop(); visitors.push( - create_visitor!(exact ast_path, visit_mut_simple_assign_target(l: &mut SimpleAssignTarget) { - use swc_core::common::Spanned; - match &imported_ident { - ImportedIdent::Module(imported_ident) => { - *l = match make_module_expr(imported_ident, export.as_deref(), l.span(), false) { - Expr::Ident(ident) => SimpleAssignTarget::Ident(ident.into()), - Expr::Member(member) => SimpleAssignTarget::Member(member), - _ => unreachable!(), - }; - } - ImportedIdent::Local(local_ident, marks) => { - *l = SimpleAssignTarget::Ident(make_local_expr(local_ident, export.as_deref(), l.span(), *marks).into()); - } - ImportedIdent::None => { - // Do nothing, cannot assign to `undefined` - } - ImportedIdent::Unresolvable => { - // Do nothing, the reference will insert a throw + create_visitor!(exact ast_path, visit_mut_simple_assign_target(l: &mut SimpleAssignTarget) { + use swc_core::common::Spanned; + match &imported_ident { + ImportedIdent::Module(imported_ident) => { + *l = imported_ident + .as_expr_individual(l.span()) + .map_either( + |i| SimpleAssignTarget::Ident(i.into()), + SimpleAssignTarget::Member, + ) + .into_inner(); + } + ImportedIdent::None => { + // Do nothing, cannot assign to `undefined` + } + ImportedIdent::Unresolvable => { + // Do nothing, the reference will insert a throw + } } - } - })); + }) + ); break; } } @@ -248,68 +186,3 @@ impl From for CodeGen { CodeGen::EsmBinding(val) } } - -fn make_module_expr( - imported_module: &str, - export: Option<&str>, - span: Span, - in_call: bool, -) -> Expr { - if let Some(export) = export { - let mut expr = Expr::Member(MemberExpr { - span, - obj: Box::new(Expr::Ident(Ident::new( - imported_module.into(), - span, - Default::default(), - ))), - prop: MemberProp::Computed(ComputedPropName { - span, - expr: Box::new(Expr::Lit(Lit::Str(Str { - span, - value: export.into(), - raw: None, - }))), - }), - }); - if in_call { - expr = Expr::Seq(SeqExpr { - exprs: vec![ - Box::new(Expr::Lit(Lit::Num(Number { - span, - value: 0.0, - raw: None, - }))), - Box::new(expr), - ], - span, - }); - } - expr - } else { - Expr::Ident(Ident::new(imported_module.into(), span, Default::default())) - } -} - -fn make_local_expr( - local_module: &str, - _export: Option<&str>, - span: Span, - marks: [Mark; 2], -) -> Ident { - // if let Some(export) = export { - // Ident::new( - // format!("{local_module}_{export}").into(), - // span, - // Default::default(), - // ) - // } else { - Ident::new( - local_module.into(), - span, - SyntaxContext::empty() - .apply_mark(marks[0]) - .apply_mark(marks[1]), - ) - // } -} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 159c11048f8f7..afba14c0a1aae 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -625,54 +625,41 @@ impl EsmExports { EsmExport::ImportedBinding(esm_ref, name, mutable) => { let referenced_asset = ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?; - referenced_asset.get_ident( - chunking_context - ).await?.map(|ident| { - let expr = MemberExpr { - span: DUMMY_SP, - obj: Box::new(Expr::Ident(Ident::new( - ident.into(), - DUMMY_SP, - Default::default(), - ))), - prop: MemberProp::Computed(ComputedPropName { - span: DUMMY_SP, - expr: Box::new(Expr::Lit(Lit::Str(Str { - span: DUMMY_SP, - value: (name as &str).into(), - raw: None, - }))), - }), - }; - if *mutable { - quote!( - "([() => $expr, ($new) => $lhs = $new])" as Expr, - expr: Expr = Expr::Member(expr.clone()), - lhs: AssignTarget = AssignTarget::Simple(SimpleAssignTarget::Member(expr)), - new = Ident::new( - format!("new_{name}").into(), - DUMMY_SP, - Default::default() - ), - ) - } else { - quote!( - "(() => $expr)" as Expr, - expr: Expr = Expr::Member(expr), - ) - } - }) + referenced_asset + .get_ident(chunking_context, Some(name.clone()), scope_hoisting_context) + .await? + .map(|ident| { + let expr = ident.as_expr_individual(DUMMY_SP); + if *mutable { + quote!( + "([() => $expr, ($new) => $lhs = $new])" as Expr, + expr: Expr = expr.clone().map_either(Expr::from, Expr::from).into_inner(), + lhs: AssignTarget = AssignTarget::Simple( + expr.map_either(|i| SimpleAssignTarget::Ident(i.into()), SimpleAssignTarget::Member).into_inner()), + new = Ident::new( + format!("new_{name}").into(), + DUMMY_SP, + Default::default() + ), + ) + } else { + quote!( + "(() => $expr)" as Expr, + expr: Expr = expr.map_either(Expr::from, Expr::from).into_inner() + ) + } + }) } EsmExport::ImportedNamespace(esm_ref) => { let referenced_asset = ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?; referenced_asset - .get_ident(chunking_context) + .get_ident(chunking_context, None, scope_hoisting_context) .await? .map(|ident| { quote!( "(() => $imported)" as Expr, - imported = Ident::new(ident.into(), DUMMY_SP, Default::default()) + imported: Expr = ident.as_expr(DUMMY_SP, false) ) }) } 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 21cc8970192a7..c4601083d99bc 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result, bail}; -use swc_core::{common::DUMMY_SP, ecma::ast::Ident, quote}; +use swc_core::{common::DUMMY_SP, quote}; use turbo_rcstr::RcStr; use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use turbopack_core::{ @@ -142,9 +142,11 @@ impl EcmascriptModulePartReference { let referenced_asset = ReferencedAsset::from_resolve_result(self.resolve_reference()); let referenced_asset = referenced_asset.await?; let ident = referenced_asset - .get_ident(chunking_context) + .get_ident(chunking_context, None, None) .await? - .context("part module reference should have an ident")?; + .context("part module reference should have an ident")? + .as_expr_individual(DUMMY_SP) + .unwrap_left(); let ReferencedAsset::Some(module) = *referenced_asset else { bail!("part module reference should have an module reference"); @@ -152,10 +154,10 @@ impl EcmascriptModulePartReference { let id = module.chunk_item_id(Vc::upcast(chunking_context)).await?; Ok(CodeGeneration::hoisted_stmt( - ident.clone().into(), + ident.sym.as_str().into(), quote!( "var $name = $turbopack_import($id);" as Stmt, - name = Ident::new(ident.clone().into(), DUMMY_SP, Default::default()), + name = ident, turbopack_import: Expr = TURBOPACK_IMPORT.into(), id: Expr = module_id_to_lit(&id), ), From 575be37c0c4627381381be8bb2c6af3c5b68dad7 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 22:18:08 +0200 Subject: [PATCH 17/59] WIP MergedModules externals --- .../src/module_graph/merged_modules.rs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 00b5124c92c3a..bbd3600d199dd 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -79,20 +79,24 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result>(); + // For each module, the indices in the bitmap store which merge group entry modules + // transitively import that module. The bitmap can be treated as an opaque value, merging + // all modules with the same bitmap. let mut module_merged_groups: FxHashMap>, RoaringBitmapWrapper> = FxHashMap::default(); + // Modules that have a reference to a module that is not in the same group (i.e. the + // quasi-leafs of the merged subgraph) + let mut modules_with_externals_references = FxHashSet::default(); + let mut next_index = 0u32; let visit_count = module_graph .traverse_edges_fixed_point_with_priority( entries.iter().map(|e| (*e, 0)), - &mut module_merged_groups, + &mut (), |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ ChunkingType)>, node: &'_ SingleModuleGraphModuleNode, - module_merged_groups: &mut FxHashMap< - ResolvedVc>, - RoaringBitmapWrapper, - >| + _| -> Result { // On the down traversal, establish which edges are mergable and set the list // indices. @@ -123,10 +127,8 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result Result { let current = entry.get_mut(); From 0cdcdbfb144446e7bc4a016a5cff671b35f538b1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 22:21:50 +0200 Subject: [PATCH 18/59] fixup codegen --- .../src/references/async_module.rs | 5 +---- .../turbopack-ecmascript/src/references/esm/base.rs | 2 +- .../src/references/esm/binding.rs | 12 +++--------- .../src/references/esm/export.rs | 4 ++-- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index fbf8739e85204..01a616d169488 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -16,10 +16,7 @@ use turbopack_core::{ }; use super::esm::base::ReferencedAsset; -use crate::{ - code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, - references::esm::base::ReferencedAssetIdent, -}; +use crate::code_gen::{CodeGeneration, CodeGenerationHoistedStmt}; /// Information needed for generating the async module wrapper for /// [EcmascriptChunkItem](crate::chunk::EcmascriptChunkItem)s. diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index ca786b6554da7..4b5ec764f346f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -2,7 +2,7 @@ use anyhow::{Result, anyhow, bail}; use either::Either; use strsim::jaro; use swc_core::{ - common::{BytePos, DUMMY_SP, Mark, Span, SyntaxContext}, + common::{BytePos, DUMMY_SP, Span, SyntaxContext}, ecma::ast::{ ComputedPropName, Decl, Expr, ExprStmt, Ident, Lit, MemberExpr, MemberProp, Number, SeqExpr, Stmt, Str, diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs index 2c908b70d739d..733aec38ab9e0 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -1,14 +1,8 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; -use swc_core::{ - common::{Span, SyntaxContext}, - ecma::{ - ast::{ - ComputedPropName, Expr, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, Number, Prop, - PropName, SeqExpr, SimpleAssignTarget, Str, - }, - visit::fields::{CalleeField, PropField}, - }, +use swc_core::ecma::{ + ast::{Expr, KeyValueProp, Prop, PropName, SimpleAssignTarget}, + visit::fields::{CalleeField, PropField}, }; use turbo_rcstr::RcStr; use turbo_tasks::{NonLocalValue, ResolvedVc, Vc, trace::TraceRawVcs}; diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index afba14c0a1aae..7f23693010f7d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize}; use swc_core::{ common::DUMMY_SP, ecma::ast::{ - AssignTarget, ComputedPropName, Expr, ExprStmt, Ident, KeyValueProp, Lit, MemberExpr, - MemberProp, ObjectLit, Prop, PropName, PropOrSpread, SimpleAssignTarget, Stmt, Str, + AssignTarget, Expr, ExprStmt, Ident, KeyValueProp, ObjectLit, Prop, PropName, PropOrSpread, + SimpleAssignTarget, Stmt, Str, }, quote, quote_expr, }; From 82aac4d711b0da09610608fae3e94ed284a143b3 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 13 May 2025 22:35:29 +0200 Subject: [PATCH 19/59] fixup MergedEcmascriptModule --- .../crates/turbopack-ecmascript/src/lib.rs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 775ec3f52f14f..67d2c57773b14 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -710,8 +710,6 @@ impl MergeableModule for EcmascriptModuleAsset { ) -> Result> { let modules = modules.await?; - let mut skipped = 0u32; - async fn is_eligible( module: ResolvedVc>, ) -> Result>>> { @@ -763,38 +761,42 @@ impl MergeableModule for EcmascriptModuleAsset { // }; // let consumed_modules = modules[start_idx..start_idx + length].to_vec(); - let mut modules = modules.iter(); + let mut modules = modules.iter().zip(0u32..); let mut merged_modules = vec![]; - while let Some(first) = modules.next() { + let mut start_index = 0; + while let Some((first, first_i)) = modules.next() { // Skip some modules, try to find the first eligible module if let Some(first) = is_eligible(*first).await? { + if merged_modules.is_empty() { + start_index = first_i; + } merged_modules.push(first); + // Consume as many modules as possible to merge together - for m in &mut modules { + for (m, _) in &mut modules { if let Some(m) = is_eligible(*m).await? { merged_modules.push(m); } else { - skipped += 1 + (merged_modules.len() as u32); break; } } + + // List has ended or incompatible module encountered if merged_modules.len() > 1 { - // Successfully found something to merge + // ... but we successfully found something to merge. break; - } else { - // Only a single module, ignore this one and try to find a bigger - // sequence in the remaining list. - merged_modules.clear(); } - } else { - skipped += 1; + + // Only a single module, ignore and try to find a bigger sequence in the remaining + // list. + merged_modules.clear(); } } - if !merged_modules.is_empty() { + if merged_modules.len() > 1 { Ok(MergeableModuleResult::Merged { consumed: merged_modules.len() as u32, - skipped, + skipped: start_index, merged_module: ResolvedVc::upcast(MergedEcmascriptModule::new( merged_modules, // TODO where to get options from? From ce98008210a58813f0bf91b9e81dccf5e742c2f6 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 14 May 2025 09:20:57 +0200 Subject: [PATCH 20/59] fixup MergedModules infinite loop --- .../src/module_graph/merged_modules.rs | 124 +++++++++++------- 1 file changed, 74 insertions(+), 50 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index bbd3600d199dd..e03add40932c9 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -83,13 +83,25 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result>, RoaringBitmapWrapper> = - FxHashMap::default(); + FxHashMap::with_capacity_and_hasher(module_count, Default::default()); + // Entries that started a new merge group for some deopt reason + let mut entry_modules = + FxHashSet::with_capacity_and_hasher(module_count, Default::default()); // Modules that have a reference to a module that is not in the same group (i.e. the // quasi-leafs of the merged subgraph) let mut modules_with_externals_references = FxHashSet::default(); let mut next_index = 0u32; + // let idents = graphs + // .iter() + // .flat_map(|g| g.graph.node_weights()) + // .map(async |n| Ok((n.module(), n.module().ident().to_string().await?))) + // .try_join() + // .await? + // .into_iter() + // .collect::>(); + let visit_count = module_graph .traverse_edges_fixed_point_with_priority( entries.iter().map(|e| (*e, 0)), @@ -112,7 +124,18 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result {} {:?} {:?}", + // parent_module.map_or("".to_string(), |p| idents[&p].to_string()), + // idents[&module], + // parent_module, + // module, + // ); + + Ok(if parent_module.is_some_and(|p| p == module) { + // A self-reference + GraphTraversalAction::Skip + } else if let (Some(parent_module), true, true) = ( parent_module.filter(|m| { ResolvedVc::try_downcast::>(*m).is_some() }), @@ -121,62 +144,63 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result { - let current = entry.get_mut(); - if !current.contains(idx) { - // Mark and continue traversal because modified - current.insert(idx); + if let Some(parent_module) = parent_module { + modules_with_externals_references.insert(parent_module); + } + + match module_merged_groups.entry(module) { + Entry::Occupied(mut entry) => { + let current = entry.get_mut(); + if !current.contains(idx) { + // Mark and continue traversal because modified + current.insert(idx); + GraphTraversalAction::Continue + } else { + // Unchanged, no need to forward to children + GraphTraversalAction::Skip + } + } + Entry::Vacant(entry) => { + // First visit + entry.insert(RoaringBitmapWrapper( + RoaringBitmap::from_sorted_iter(std::iter::once(idx)) + .unwrap(), + )); GraphTraversalAction::Continue - } else { - // Unchanged, no need to forward to children - GraphTraversalAction::Skip } } - Entry::Vacant(entry) => { - // First visit - entry.insert(RoaringBitmapWrapper( - RoaringBitmap::from_sorted_iter(std::iter::once(idx)).unwrap(), - )); - GraphTraversalAction::Continue - } + } else { + // Already visited and assigned a new group, no need to forward to + // children. + GraphTraversalAction::Skip } }) }, From 22371f31c265374800bb1b772445464d3a2b4563 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 14 May 2025 10:49:22 +0200 Subject: [PATCH 21/59] fix namespace imports inside merged group --- .../crates/turbopack-ecmascript/src/references/esm/base.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 4b5ec764f346f..386bd9e5fe3e8 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -477,8 +477,10 @@ impl EsmAssetReference { unreachable!() } ReferencedAsset::Some(asset) => { + // TODO support namespace imports within a merged group as well if scope_hoisting_context .is_some_and(|c| c.modules.contains_key(&ResolvedVc::upcast(*asset))) + && this.export_name.is_some() { // No need to import, the module is already available in the same scope // hoisting group. From e96468d161abf8477ccb79a7f3d251e1e3fad604 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 14 May 2025 14:23:48 +0200 Subject: [PATCH 22/59] Implement __turbopack_esm_other__ differently --- .../js/src/browser/runtime/base/build-base.ts | 9 +-- .../js/src/browser/runtime/base/dev-base.ts | 9 +-- .../js/src/nodejs/runtime.ts | 9 +-- .../js/src/shared/runtime-types.d.ts | 17 ++-- .../js/src/shared/runtime-utils.ts | 81 ++++++++++++------- .../src/runtime_functions.rs | 5 +- 6 files changed, 74 insertions(+), 56 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts index 2c91aace2b843..71a2ea5308faf 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts @@ -109,11 +109,10 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { t: runtimeRequire, f: moduleContext, i: esmImport.bind(null, module), - s: esmExport.bind(null, module, module.exports), - o: esmExportOther.bind(null, moduleCache), - j: dynamicExport.bind(null, module, module.exports), - v: exportValue.bind(null, module), - n: exportNamespace.bind(null, module), + s: esmExport.bind(null, module, module.exports, moduleCache), + j: dynamicExport.bind(null, module, module.exports, moduleCache), + v: exportValue.bind(null, module, moduleCache), + n: exportNamespace.bind(null, module, moduleCache), m: module, c: moduleCache, M: moduleFactories, diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts index 91359d2ff241a..296efdd325c88 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/dev-base.ts @@ -205,11 +205,10 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { t: runtimeRequire, f: moduleContext, i: esmImport.bind(null, module), - s: esmExport.bind(null, module, module.exports), - o: esmExportOther.bind(null, devModuleCache), - j: dynamicExport.bind(null, module, module.exports), - v: exportValue.bind(null, module), - n: exportNamespace.bind(null, module), + s: esmExport.bind(null, module, module.exports, devModuleCache), + j: dynamicExport.bind(null, module, module.exports, devModuleCache), + v: exportValue.bind(null, module, devModuleCache), + n: exportNamespace.bind(null, module, devModuleCache), m: module, c: devModuleCache, M: moduleFactories, diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts index 4ab0206c8f503..77a1d6d84eb6d 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -286,11 +286,10 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { y: externalImport, f: moduleContext, i: esmImport.bind(null, module), - s: esmExport.bind(null, module, module.exports), - o: esmExportOther.bind(null, moduleCache), - j: dynamicExport.bind(null, module, module.exports), - v: exportValue.bind(null, module), - n: exportNamespace.bind(null, module), + s: esmExport.bind(null, module, module.exports, moduleCache), + j: dynamicExport.bind(null, module, module.exports, moduleCache), + v: exportValue.bind(null, module, moduleCache), + n: exportNamespace.bind(null, module, moduleCache), m: module, c: moduleCache, M: moduleFactories, diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts index 3f555f338bd67..89f79ab8d5e73 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts @@ -37,14 +37,16 @@ type EsmImport = ( moduleId: ModuleId, allowExportDefault: boolean ) => EsmNamespaceObject | Promise -type EsmExport = (exportGetters: Record any>) => void -type EsmExportOther = ( - id: ModuleId, - exportGetters: Record any> +type EsmExport = ( + exportGetters: Record any>, + id: ModuleId | undefined +) => void +type ExportValue = (value: any, id: ModuleId | undefined) => void +type ExportNamespace = (namespace: any, id: ModuleId | undefined) => void +type DynamicExport = ( + object: Record, + id: ModuleId | undefined ) => void -type ExportValue = (value: any) => void -type ExportNamespace = (namespace: any) => void -type DynamicExport = (object: Record) => void type LoadChunk = (chunkPath: ChunkPath) => Promise | undefined type LoadChunkByUrl = (chunkUrl: ChunkUrl) => Promise | undefined @@ -108,7 +110,6 @@ interface TurbopackBaseContext { f: ModuleContextFactory i: EsmImport s: EsmExport - o: EsmExportOther j: DynamicExport v: ExportValue n: ExportNamespace diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts index 413eb72890158..3a5d22fce5fda 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts @@ -59,6 +59,26 @@ function defineProp( if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options) } +function getOverwrittenModule( + moduleCache: ModuleCache, + id: ModuleId +): Module { + let module = moduleCache[id] + if (!module) { + // This is invoked when a module is merged into another module, thus it wasn't invoced via + // instantiateModule and the cache entry wasn't created yet. + module = { + exports: {}, + error: undefined, + loaded: false, + id, + namespaceObject: undefined, + } + moduleCache[id] = module + } + return module +} + /** * Adds the getters to the exports object. */ @@ -89,8 +109,14 @@ function esm( function esmExport( module: Module, exports: Exports, - getters: Record any> + moduleCache: ModuleCache, + getters: Record any>, + id: ModuleId | undefined ) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id) + exports = module.exports + } module.namespaceObject = module.exports esm(exports, getters) } @@ -128,39 +154,20 @@ function ensureDynamicExports(module: Module, exports: Exports) { } } -/** - * Makes the specified module an ESM with exports - */ -function esmExportOther( - moduleCache: ModuleCache, - id: ModuleId, - getters: Record any> -) { - let module = moduleCache[id] - if (!module) { - // This is invoked when a module is merged into another module, thus it wasn't invoced via - // instantiateModule and the cache entry wasn't created yet. - module = { - exports: {}, - error: undefined, - loaded: false, - id, - namespaceObject: undefined, - } - moduleCache[id] = module - } - module.namespaceObject = module.exports - esm(module.exports, getters) -} - /** * Dynamically exports properties from an object */ function dynamicExport( module: Module, exports: Exports, - object: Record + moduleCache: ModuleCache, + object: Record, + id: ModuleId | undefined ) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id) + exports = module.exports + } ensureDynamicExports(module, exports) if (typeof object === 'object' && object !== null) { @@ -168,11 +175,27 @@ function dynamicExport( } } -function exportValue(module: Module, value: any) { +function exportValue( + module: Module, + moduleCache: ModuleCache, + value: any, + id: ModuleId | undefined +) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id) + } module.exports = value } -function exportNamespace(module: Module, namespace: any) { +function exportNamespace( + module: Module, + moduleCache: ModuleCache, + namespace: any, + id: ModuleId | undefined +) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id) + } module.exports = module.namespaceObject = namespace } diff --git a/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs b/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs index aa12c7c8d78ff..d09aa3ec61f2f 100644 --- a/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs +++ b/turbopack/crates/turbopack-ecmascript/src/runtime_functions.rs @@ -44,8 +44,6 @@ pub const TURBOPACK_IMPORT: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.i", "i"); pub const TURBOPACK_ESM: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.s", "s"); -pub const TURBOPACK_ESM_OTHER: &TurbopackRuntimeFunctionShortcut = - &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.o", "o"); pub const TURBOPACK_EXPORT_VALUE: &TurbopackRuntimeFunctionShortcut = &TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.v", "v"); pub const TURBOPACK_EXPORT_NAMESPACE: &TurbopackRuntimeFunctionShortcut = @@ -83,12 +81,11 @@ pub const TURBOPACK_REQUIRE_REAL: &TurbopackRuntimeFunctionShortcut = /// Adding an entry to this list will automatically ensure that `__turbopack_XXX__` can be called /// from user code (by inserting a replacement into free_var_references) -pub const TUBROPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 22] = [ +pub const TUBROPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 21] = [ ("__turbopack_require__", TURBOPACK_REQUIRE), ("__turbopack_module_context__", TURBOPACK_MODULE_CONTEXT), ("__turbopack_import__", TURBOPACK_IMPORT), ("__turbopack_esm__", TURBOPACK_ESM), - ("__turbopack_esm_other__", TURBOPACK_ESM_OTHER), ("__turbopack_export_value__", TURBOPACK_EXPORT_VALUE), ("__turbopack_export_namespace__", TURBOPACK_EXPORT_NAMESPACE), ("__turbopack_cache__", TURBOPACK_CACHE), From d1c0ca7d6a4ccfa5fc92e9ad69b8e1605fe75065 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 14 May 2025 14:23:59 +0200 Subject: [PATCH 23/59] fixup codegen --- .../src/references/esm/export.rs | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 7f23693010f7d..08bc8bcedbf02 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -569,16 +569,42 @@ impl EsmExports { }; let mut dynamic_exports = Vec::>::new(); - for dynamic_export_asset in &expanded.dynamic_exports { - let ident = - ReferencedAsset::get_ident_from_placeable(dynamic_export_asset, chunking_context) - .await?; - - dynamic_exports.push(quote_expr!( - "$turbopack_dynamic($arg)", - turbopack_dynamic: Expr = TURBOPACK_DYNAMIC.into(), - arg: Expr = Ident::new(ident.into(), DUMMY_SP, Default::default()).into() - )); + { + let id = if let Some(scope_hoisting_context) = scope_hoisting_context + && !expanded.dynamic_exports.is_empty() + { + Some( + scope_hoisting_context + .module + .chunk_item_id(Vc::upcast(chunking_context)) + .await?, + ) + } else { + None + }; + + for dynamic_export_asset in &expanded.dynamic_exports { + let ident = ReferencedAsset::get_ident_from_placeable( + dynamic_export_asset, + chunking_context, + ) + .await?; + + if let Some(id) = &id { + dynamic_exports.push(quote_expr!( + "$turbopack_dynamic($arg, $id)", + turbopack_dynamic: Expr = TURBOPACK_DYNAMIC.into(), + arg: Expr = Ident::new(ident.into(), DUMMY_SP, Default::default()).into(), + id: Expr = module_id_to_lit(id) + )); + } else { + dynamic_exports.push(quote_expr!( + "$turbopack_dynamic($arg)", + turbopack_dynamic: Expr = TURBOPACK_DYNAMIC.into(), + arg: Expr = Ident::new(ident.into(), DUMMY_SP, Default::default()).into() + )); + } + } } let mut getters = Vec::new(); @@ -701,10 +727,10 @@ impl EsmExports { .module .chunk_item_id(Vc::upcast(chunking_context)) .await?; - quote!("$turbopack_esm_other($id, $getters);" as Stmt, - turbopack_esm_other: Expr = TURBOPACK_ESM_OTHER.into(), - id: Expr = module_id_to_lit(&id), - getters: Expr = getters + quote!("$turbopack_esm($getters, $id);" as Stmt, + turbopack_esm: Expr = TURBOPACK_ESM.into(), + getters: Expr = getters, + id: Expr = module_id_to_lit(&id) ) }, )) From 63c521cf344f3ad901ca920c1f3cf19f0a886bdc Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 14 May 2025 14:31:41 +0200 Subject: [PATCH 24/59] Require missing exports --- .../turbopack-ecmascript/src/references/esm/base.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 386bd9e5fe3e8..dd7cdd380b1c2 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -184,8 +184,16 @@ impl ReferencedAsset { )) .await; } + None => { + // Export not found, either there was already an error, or + // this is some dynamic (CJS) (re)export situation. + } _ => { - todo!("TODO {:?}", export) + todo!( + "TODO {:?} {:?}", + asset.ident().to_string().await?, + export + ) } } } From 2be2e5e2002daa1b7ee851b4010381508d41ef58 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 17:26:44 +0200 Subject: [PATCH 25/59] Don't expose all modules --- .../crates/turbopack-core/src/chunk/mod.rs | 4 +- .../src/module_graph/merged_modules.rs | 30 +- .../turbopack-core/src/module_graph/mod.rs | 2 +- .../crates/turbopack-ecmascript/src/lib.rs | 19 +- .../turbopack-ecmascript/src/merged_module.rs | 11 +- .../src/references/esm/base.rs | 257 +++++++++--------- 6 files changed, 171 insertions(+), 152 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 4b9d312940103..16c20c31a1402 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -129,12 +129,12 @@ pub trait MergeableModule: Module + Asset { fn merge(self: Vc, modules: Vc) -> Vc; } #[turbo_tasks::value(transparent)] -pub struct MergeableModules(Vec>>); +pub struct MergeableModules(Vec<(ResolvedVc>, bool)>); #[turbo_tasks::value_impl] impl MergeableModules { #[turbo_tasks::function] - pub fn interned(modules: Vec>>) -> Vc { + pub fn interned(modules: Vec<(ResolvedVc>, bool)>) -> Vc { Vc::cell(modules) } } diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index e03add40932c9..3909920b064b5 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -57,7 +57,7 @@ impl MergedModuleInfo { /// treated as one. /// - if a merged module has an incoming edge not contained in the group, it has to expose its /// exports into the module cache. -pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result> { +pub async fn compute_merged_modules(module_graph: Vc) -> Result> { let span_outer = tracing::info_span!( "compute merged modules", module_count = tracing::field::Empty, @@ -68,6 +68,8 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result(); span.record("module_count", module_count); @@ -87,9 +89,6 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result Result { let current = entry.get_mut(); @@ -231,14 +226,18 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result>>, > = FxIndexMap::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + // Modules that are referenced from outside the group, so their exports need to be exposed. + let mut exposed_modules: FxHashSet>> = + FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); module_graph .traverse_edges_from_entries_topological( entries, &mut (), |_, _, _| Ok(GraphTraversalAction::Continue), - |_, node, _| { + |parent_info, node, _| { let module = node.module; + if let Some(mergeable_module) = ResolvedVc::try_downcast::>(module) { @@ -250,6 +249,14 @@ pub async fn compute_merged_modules(module_graph: &ModuleGraph) -> Result Result>(); + let modules = list[i..] + .iter() + .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) + .collect::>(); match *first.merge(MergeableModules::interned(modules)).await? { MergeableModuleResult::Merged { merged_module, diff --git a/turbopack/crates/turbopack-core/src/module_graph/mod.rs b/turbopack/crates/turbopack-core/src/module_graph/mod.rs index 740d5194e2d4e..4c80eab459064 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/mod.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/mod.rs @@ -761,7 +761,7 @@ impl ModuleGraph { } #[turbo_tasks::function] - pub async fn merged_modules(&self) -> Result> { + pub async fn merged_modules(self: Vc) -> Result> { compute_merged_modules(self).await } diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 67d2c57773b14..56c296c35d99b 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -764,18 +764,18 @@ impl MergeableModule for EcmascriptModuleAsset { let mut modules = modules.iter().zip(0u32..); let mut merged_modules = vec![]; let mut start_index = 0; - while let Some((first, first_i)) = modules.next() { + while let Some(((first, exposed), first_i)) = modules.next() { // Skip some modules, try to find the first eligible module if let Some(first) = is_eligible(*first).await? { if merged_modules.is_empty() { start_index = first_i; } - merged_modules.push(first); + merged_modules.push((first, *exposed)); // Consume as many modules as possible to merge together - for (m, _) in &mut modules { + for ((m, exposed), _) in &mut modules { if let Some(m) = is_eligible(*m).await? { - merged_modules.push(m); + merged_modules.push((m, *exposed)); } else { break; } @@ -1094,16 +1094,15 @@ impl EcmascriptModuleContent { /// hoisting. #[turbo_tasks::function] pub async fn new_merged( - modules: Vec>>, + modules: Vec<(ResolvedVc>, bool)>, module_options: Vec>, ) -> Result> { let modules = modules - .iter() - .map(|m| { + .into_iter() + .map(|(m, exposed)| { ( - ResolvedVc::try_sidecast::>(*m).unwrap(), - // TODO when is a module exposed? - true, + ResolvedVc::try_sidecast::>(m).unwrap(), + exposed, ) }) .collect::>(); diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs index f1ce475d584af..6684107bdd568 100644 --- a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -16,13 +16,13 @@ use crate::{ #[turbo_tasks::value(shared)] pub(crate) struct MergedEcmascriptModule { - modules: Vec>>, + modules: Vec<(ResolvedVc>, bool)>, options: ResolvedVc, } impl MergedEcmascriptModule { pub fn new( - modules: Vec>>, + modules: Vec<(ResolvedVc>, bool)>, options: ResolvedVc, ) -> ResolvedVc { MergedEcmascriptModule { modules, options }.resolved_cell() @@ -43,7 +43,7 @@ impl Module for MergedEcmascriptModule { fn ident(&self) -> Vc { // This purposely reuses the module's ident as it has replaced the original module, thus // there can never be a collision. - self.modules.first().unwrap().ident() + self.modules.first().unwrap().0.ident() } #[turbo_tasks::function] @@ -132,7 +132,7 @@ impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { // ); let options = modules .iter() - .map(|m| { + .map(|(m, _)| { let Some(m) = ResolvedVc::try_downcast::>(*m) else { anyhow::bail!("Expected EcmascriptAnalyzable in scope hoisting group"); }; @@ -144,8 +144,7 @@ impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { }) .collect::>>()?; - let content = - EcmascriptModuleContent::new_merged(modules.iter().map(|m| **m).collect(), options); + let content = EcmascriptModuleContent::new_merged(modules.clone(), options); // TODO async let async_module_options = Vc::cell(None); diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index dd7cdd380b1c2..9a3bde7e515f6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -58,6 +58,7 @@ pub enum ReferencedAsset { Unresolvable, } +#[derive(Debug)] pub enum ReferencedAssetIdent { LocalBinding { ident: RcStr, @@ -460,135 +461,145 @@ impl EsmAssetReference { let result = if this.annotations.chunking_type() != Some("none") { let import_externals = this.import_externals; let referenced_asset = self.get_referenced_asset().await?; - if let ReferencedAsset::Unresolvable = &*referenced_asset { - // Insert code that throws immediately at time of import if a request is - // unresolvable - let request = request_to_string(*this.request).await?.to_string(); - let stmt = Stmt::Expr(ExprStmt { - expr: Box::new(throw_module_not_found_expr(&request)), - span: DUMMY_SP, - }); - Some((format!("throw {request}").into(), stmt)) - } else if let Some(ident) = referenced_asset - .get_ident(chunking_context, None, scope_hoisting_context) - .await? - { - let span = this - .issue_source - .to_swc_offsets() - .await? - .map_or(DUMMY_SP, |(start, end)| { - Span::new(BytePos(start), BytePos(end)) + + match &*referenced_asset { + ReferencedAsset::Unresolvable => { + // Insert code that throws immediately at time of import if a request is + // unresolvable + let request = request_to_string(*this.request).await?.to_string(); + let stmt = Stmt::Expr(ExprStmt { + expr: Box::new(throw_module_not_found_expr(&request)), + span: DUMMY_SP, }); - match &*referenced_asset { - ReferencedAsset::Unresolvable => { - unreachable!() - } - ReferencedAsset::Some(asset) => { - // TODO support namespace imports within a merged group as well - if scope_hoisting_context + Some((format!("throw {request}").into(), stmt)) + } + ReferencedAsset::None => None, + _ => { + if let ReferencedAsset::Some(asset) = &*referenced_asset + && scope_hoisting_context .is_some_and(|c| c.modules.contains_key(&ResolvedVc::upcast(*asset))) - && this.export_name.is_some() - { - // No need to import, the module is already available in the same scope - // hoisting group. - None - } else { - let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; - let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( - id.to_string().into(), - var_decl_with_span( - quote!( - "var $name = $turbopack_import($id);" as Stmt, - name = name, - turbopack_import: Expr = TURBOPACK_IMPORT.into(), - id: Expr = module_id_to_lit(&id), - ), - span, - ), - )) - } - } - ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => { - if !*chunking_context - .environment() - .supports_esm_externals() - .await? - { - bail!( - "the chunking context ({}) does not support external modules (esm \ - request: {})", - chunking_context.name().await?, - request - ); - } - let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( - name.sym.as_str().into(), - var_decl_with_span( - if import_externals { - quote!( - "var $name = $turbopack_external_import($id);" as Stmt, - name = name, - turbopack_external_import: Expr = TURBOPACK_EXTERNAL_IMPORT.into(), - id: Expr = Expr::Lit(request.clone().to_string().into()) - ) - } else { - quote!( - "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, - name = name, - turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), - id: Expr = Expr::Lit(request.clone().to_string().into()) - ) - }, - span, - ), - )) - } - ReferencedAsset::External( - request, - ExternalType::CommonJs | ExternalType::Url, - ) => { - if !*chunking_context - .environment() - .supports_commonjs_externals() + && !this + .export_name + .as_ref() + .is_none_or(|e| matches!(e, ModulePart::Exports)) + { + // No need to import, the module is already available in the same scope + // hoisting group. + // And it's not requiring a namespace import, + None + } else if let Some(ident) = referenced_asset + .get_ident(chunking_context, None, scope_hoisting_context) + .await? + { + let span = this + .issue_source + .to_swc_offsets() .await? - { - bail!( - "the chunking context ({}) does not support external modules \ - (request: {})", - chunking_context.name().await?, - request - ); + .map_or(DUMMY_SP, |(start, end)| { + Span::new(BytePos(start), BytePos(end)) + }); + match &*referenced_asset { + ReferencedAsset::Unresolvable => { + unreachable!() + } + ReferencedAsset::Some(asset) => { + let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); + Some(( + id.to_string().into(), + var_decl_with_span( + quote!( + "var $name = $turbopack_import($id);" as Stmt, + name = name, + turbopack_import: Expr = TURBOPACK_IMPORT.into(), + id: Expr = module_id_to_lit(&id), + ), + span, + ), + )) + } + ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => { + if !*chunking_context + .environment() + .supports_esm_externals() + .await? + { + bail!( + "the chunking context ({}) does not support external \ + modules (esm request: {})", + chunking_context.name().await?, + request + ); + } + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); + Some(( + name.sym.as_str().into(), + var_decl_with_span( + if import_externals { + quote!( + "var $name = $turbopack_external_import($id);" as Stmt, + name = name, + turbopack_external_import: Expr = TURBOPACK_EXTERNAL_IMPORT.into(), + id: Expr = Expr::Lit(request.clone().to_string().into()) + ) + } else { + quote!( + "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, + name = name, + turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), + id: Expr = Expr::Lit(request.clone().to_string().into()) + ) + }, + span, + ), + )) + } + ReferencedAsset::External( + request, + ExternalType::CommonJs | ExternalType::Url, + ) => { + if !*chunking_context + .environment() + .supports_commonjs_externals() + .await? + { + bail!( + "the chunking context ({}) does not support external \ + modules (request: {})", + chunking_context.name().await?, + request + ); + } + let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); + Some(( + name.sym.as_str().into(), + var_decl_with_span( + quote!( + "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, + name = name, + turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), + id: Expr = Expr::Lit(request.clone().to_string().into()) + ), + span, + ), + )) + } + // fallback in case we introduce a new `ExternalType` + #[allow(unreachable_patterns)] + ReferencedAsset::External(request, ty) => { + bail!( + "Unsupported external type {:?} for ESM reference with \ + request: {:?}", + ty, + request + ) + } + ReferencedAsset::None => None, } - let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( - name.sym.as_str().into(), - var_decl_with_span( - quote!( - "var $name = $turbopack_external_require($id, () => require($id), true);" as Stmt, - name = name, - turbopack_external_require: Expr = TURBOPACK_EXTERNAL_REQUIRE.into(), - id: Expr = Expr::Lit(request.clone().to_string().into()) - ), - span, - ), - )) - } - // fallback in case we introduce a new `ExternalType` - #[allow(unreachable_patterns)] - ReferencedAsset::External(request, ty) => { - bail!( - "Unsupported external type {:?} for ESM reference with request: {:?}", - ty, - request - ) + } else { + None } - ReferencedAsset::None => None, } - } else { - None } } else { None From 53cde91633b56a26970fde5011b8daba7f272b44 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 15 May 2025 16:30:30 +0200 Subject: [PATCH 26/59] cleanup --- .../src/references/esm/export.rs | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 08bc8bcedbf02..8222b11c5fb35 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -561,6 +561,11 @@ impl EsmExports { parsed: Option>, export_usage_info: Option>, ) -> Result { + if scope_hoisting_context.is_some_and(|ctx| !*ctx.modules.get(&ctx.module).unwrap()) { + // If the current module is not exposed, no need to generate exports + return Ok(CodeGeneration::empty()); + } + let expanded = self.expand_exports(export_usage_info.map(|v| *v)).await?; let parsed = if let Some(parsed) = parsed { Some(parsed.await?) @@ -714,45 +719,25 @@ impl EsmExports { None }; - let early_hoisted_stmts = if let Some(scope_hoisting_context) = scope_hoisting_context { - let exposed = *scope_hoisting_context - .modules - .get(&scope_hoisting_context.module) - .unwrap(); - let registry = if exposed { - Some(CodeGenerationHoistedStmt::new( - "__turbopack_esm__".into(), - { - let id = scope_hoisting_context - .module - .chunk_item_id(Vc::upcast(chunking_context)) - .await?; - quote!("$turbopack_esm($getters, $id);" as Stmt, - turbopack_esm: Expr = TURBOPACK_ESM.into(), - getters: Expr = getters, - id: Expr = module_id_to_lit(&id) - ) - }, - )) + let early_hoisted_stmts = vec![CodeGenerationHoistedStmt::new( + "__turbopack_esm__".into(), + if let Some(scope_hoisting_context) = scope_hoisting_context { + let id = scope_hoisting_context + .module + .chunk_item_id(Vc::upcast(chunking_context)) + .await?; + quote!("$turbopack_esm($getters, $id);" as Stmt, + turbopack_esm: Expr = TURBOPACK_ESM.into(), + getters: Expr = getters, + id: Expr = module_id_to_lit(&id) + ) } else { - None - }; - - let local_re_bindings = vec![]; - - registry - .into_iter() - .chain(local_re_bindings.into_iter()) - .collect() - } else { - vec![CodeGenerationHoistedStmt::new( - "__turbopack_esm__".into(), quote!("$turbopack_esm($getters);" as Stmt, turbopack_esm: Expr = TURBOPACK_ESM.into(), getters: Expr = getters - ), - )] - }; + ) + }, + )]; Ok(CodeGeneration::new( vec![], From 1bf09f9c46b656363aa39633796f4e40325031d5 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 15 May 2025 15:58:45 +0200 Subject: [PATCH 27/59] Async modules aren't mergeable --- .../turbopack-core/src/module_graph/merged_modules.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 3909920b064b5..d7a95da116a31 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -68,6 +68,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result>(*m).is_some() }), ResolvedVc::try_downcast::>(module).is_some(), hoisted, + // TODO technically we could merge a sync child into an async parent + !parent_module.is_some_and(|p| async_module_info.contains(&p)) + && !async_module_info.contains(&module), ) { - // A hoisted reference from a mergeable module to a mergeable module, - // inherit bitmaps from parent. + // A hoisted reference from a mergeable module to a non-async mergeable + // module, inherit bitmaps from parent. module_merged_groups.entry(node.module).or_default(); let [Some(parent_merged_groups), Some(current_merged_groups)] = module_merged_groups.get_disjoint_mut([&parent_module, &node.module]) From 2a32e661d0d5d3cc1c7459cdac0059759f45e0ed Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 17:21:28 +0200 Subject: [PATCH 28/59] Revert "undo merged_modules" This reverts commit dec4ec97392650394f5f6022ff4e41ee6663806a. --- .../turbopack-core/src/module_graph/merged_modules.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index d7a95da116a31..ccb40446e64c2 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -14,7 +14,7 @@ use crate::{ }, module::Module, module_graph::{ - GraphTraversalAction, ModuleGraph, SingleModuleGraphModuleNode, + GraphTraversalAction, ModuleGraph, RefData, SingleModuleGraphModuleNode, chunk_group_info::RoaringBitmapWrapper, }, }; @@ -106,7 +106,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result, + |parent_info: Option<(&'_ SingleModuleGraphModuleNode, &'_ RefData)>, node: &'_ SingleModuleGraphModuleNode, _| -> Result { @@ -116,7 +116,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result *hoisted, _ => false, }, From b71014e1be6205a4aeba46298ef5e3e8e612795f Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 16 May 2025 10:02:04 +0200 Subject: [PATCH 29/59] Expose namespace imported modules --- .../turbopack-core/src/module_graph/merged_modules.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index ccb40446e64c2..88e42ea50e791 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -17,6 +17,7 @@ use crate::{ GraphTraversalAction, ModuleGraph, RefData, SingleModuleGraphModuleNode, chunk_group_info::RoaringBitmapWrapper, }, + resolve::ExportUsage, }; #[turbo_tasks::value(transparent)] @@ -254,11 +255,13 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result Date: Fri, 16 May 2025 13:59:29 +0200 Subject: [PATCH 30/59] Support ImportedNamespace reexports --- .../src/references/async_module.rs | 14 +++- .../src/references/esm/base.rs | 74 +++++++++++++------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index 01a616d169488..e8e6d66cf9c43 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -1,7 +1,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use swc_core::{ - common::DUMMY_SP, + common::{DUMMY_SP, SyntaxContext}, ecma::ast::{ArrayLit, ArrayPat, Expr, Ident}, quote, }; @@ -76,7 +76,7 @@ impl OptionAsyncModule { } #[turbo_tasks::value(transparent)] -struct AsyncModuleIdents(FxIndexSet); +struct AsyncModuleIdents(FxIndexSet<(String, u32)>); async fn get_inherit_async_referenced_asset( r: Vc>, @@ -126,6 +126,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) + .map(|(i, ctx)| (i, ctx.as_u32())) } else { None } @@ -139,6 +140,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) + .map(|(i, ctx)| (i, ctx.as_u32())) } else { None } @@ -213,8 +215,12 @@ impl AsyncModule { if !async_idents.is_empty() { let idents = async_idents .iter() - .map(|ident: &String| { - Ident::new(ident.clone().into(), DUMMY_SP, Default::default()) + .map(|(ident, ctxt)| { + Ident::new( + ident.clone().into(), + DUMMY_SP, + SyntaxContext::from_u32(*ctxt), + ) }) .collect::>(); diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 9a3bde7e515f6..17bcc5a605c1d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -66,16 +66,19 @@ pub enum ReferencedAssetIdent { }, Module { namespace_ident: String, + ctxt: SyntaxContext, export: Option, }, } impl ReferencedAssetIdent { - pub fn into_module_namespace_ident(self) -> Option { + pub fn into_module_namespace_ident(self) -> Option<(String, SyntaxContext)> { match self { ReferencedAssetIdent::Module { - namespace_ident, .. - } => Some(namespace_ident), + namespace_ident, + ctxt, + .. + } => Some((namespace_ident, ctxt)), ReferencedAssetIdent::LocalBinding { .. } => None, } } @@ -87,16 +90,14 @@ impl ReferencedAssetIdent { } ReferencedAssetIdent::Module { namespace_ident, + ctxt, export, } => { + let ns = Ident::new(namespace_ident.as_str().into(), span, *ctxt); if let Some(export) = export { Either::Right(MemberExpr { span, - obj: Box::new(Expr::Ident(Ident::new( - namespace_ident.as_str().into(), - span, - Default::default(), - ))), + obj: Box::new(Expr::Ident(ns)), prop: MemberProp::Computed(ComputedPropName { span, expr: Box::new(Expr::Lit(Lit::Str(Str { @@ -107,11 +108,7 @@ impl ReferencedAssetIdent { }), }) } else { - Either::Left(Ident::new( - namespace_ident.as_str().into(), - span, - Default::default(), - )) + Either::Left(ns) } } } @@ -185,17 +182,50 @@ impl ReferencedAsset { )) .await; } - None => { + Some(EsmExport::ImportedNamespace(esm_ref)) => { + let referenced_asset = + ReferencedAsset::from_resolve_result( + esm_ref.resolve_reference(), + ) + .await?; + + // We need the namespace object, so it needs to be imported + return Ok( + match Box::pin(referenced_asset.get_ident( + chunking_context, + None, + Some(scope_hoisting_context), + )) + .await? + { + Some(ReferencedAssetIdent::Module { + namespace_ident, + export, + // Overwrite the context. This import isn't + // inserted in the module that uses the import, + // but in the module containing the reexport + ctxt: _, + }) => Some(ReferencedAssetIdent::Module { + namespace_ident, + ctxt: *ctxt, + export, + }), + Some(ReferencedAssetIdent::LocalBinding { + .. + }) => { + bail!( + "Cannot refer to imported namespace with \ + local binding" + ) + } + None => None, + }, + ); + } + Some(EsmExport::Error) | None => { // Export not found, either there was already an error, or // this is some dynamic (CJS) (re)export situation. } - _ => { - todo!( - "TODO {:?} {:?}", - asset.ident().to_string().await?, - export - ) - } } } } @@ -205,11 +235,13 @@ impl ReferencedAsset { Some(ReferencedAssetIdent::Module { namespace_ident: Self::get_ident_from_placeable(asset, chunking_context) .await?, + ctxt: Default::default(), export, }) } ReferencedAsset::External(request, ty) => Some(ReferencedAssetIdent::Module { namespace_ident: magic_identifier::mangle(&format!("{ty} external {request}")), + ctxt: Default::default(), export, }), ReferencedAsset::None | ReferencedAsset::Unresolvable => None, From 6e07cfe4765092b927134af4eb6e24967da76543 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 16 May 2025 14:27:53 +0200 Subject: [PATCH 31/59] Fix reexports from unmerged modules --- .../src/references/async_module.rs | 4 +- .../src/references/esm/base.rs | 57 ++++++++----------- 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index e8e6d66cf9c43..227322ae6320d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -126,7 +126,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) - .map(|(i, ctx)| (i, ctx.as_u32())) + .map(|(i, ctx)| (i, ctx.unwrap_or_default().as_u32())) } else { None } @@ -140,7 +140,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) - .map(|(i, ctx)| (i, ctx.as_u32())) + .map(|(i, ctx)| (i, ctx.unwrap_or_default().as_u32())) } else { None } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 17bcc5a605c1d..67d6b39d21897 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -66,13 +66,13 @@ pub enum ReferencedAssetIdent { }, Module { namespace_ident: String, - ctxt: SyntaxContext, + ctxt: Option, export: Option, }, } impl ReferencedAssetIdent { - pub fn into_module_namespace_ident(self) -> Option<(String, SyntaxContext)> { + pub fn into_module_namespace_ident(self) -> Option<(String, Option)> { match self { ReferencedAssetIdent::Module { namespace_ident, @@ -93,7 +93,11 @@ impl ReferencedAssetIdent { ctxt, export, } => { - let ns = Ident::new(namespace_ident.as_str().into(), span, *ctxt); + let ns = Ident::new( + namespace_ident.as_str().into(), + span, + ctxt.unwrap_or_default(), + ); if let Some(export) = export { Either::Right(MemberExpr { span, @@ -166,7 +170,15 @@ impl ReferencedAsset { ctxt: *ctxt, })); } - Some(EsmExport::ImportedBinding(esm_ref, name, _)) => { + Some(b @ EsmExport::ImportedBinding(esm_ref, _, _)) + | Some(b @ EsmExport::ImportedNamespace(esm_ref)) => { + let export = + if let EsmExport::ImportedBinding(_, export, _) = b { + Some(export.clone()) + } else { + None + }; + let referenced_asset = ReferencedAsset::from_resolve_result( esm_ref.resolve_reference(), @@ -175,50 +187,27 @@ impl ReferencedAsset { // If the target module is still in the same group, we can // refer it locally, otherwise it will be imported - return Box::pin(referenced_asset.get_ident( - chunking_context, - Some(name.clone()), - Some(scope_hoisting_context), - )) - .await; - } - Some(EsmExport::ImportedNamespace(esm_ref)) => { - let referenced_asset = - ReferencedAsset::from_resolve_result( - esm_ref.resolve_reference(), - ) - .await?; - - // We need the namespace object, so it needs to be imported return Ok( match Box::pin(referenced_asset.get_ident( chunking_context, - None, + export, Some(scope_hoisting_context), )) .await? { Some(ReferencedAssetIdent::Module { namespace_ident, - export, // Overwrite the context. This import isn't // inserted in the module that uses the import, // but in the module containing the reexport - ctxt: _, + ctxt: None, + export, }) => Some(ReferencedAssetIdent::Module { namespace_ident, - ctxt: *ctxt, + ctxt: Some(*ctxt), export, }), - Some(ReferencedAssetIdent::LocalBinding { - .. - }) => { - bail!( - "Cannot refer to imported namespace with \ - local binding" - ) - } - None => None, + ident => ident, }, ); } @@ -235,13 +224,13 @@ impl ReferencedAsset { Some(ReferencedAssetIdent::Module { namespace_ident: Self::get_ident_from_placeable(asset, chunking_context) .await?, - ctxt: Default::default(), + ctxt: None, export, }) } ReferencedAsset::External(request, ty) => Some(ReferencedAssetIdent::Module { namespace_ident: magic_identifier::mangle(&format!("{ty} external {request}")), - ctxt: Default::default(), + ctxt: None, export, }), ReferencedAsset::None | ReferencedAsset::Unresolvable => None, From 54427e73ec153ebb75a5c25d6f47b7cf70f0546c Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 16 May 2025 14:45:44 +0200 Subject: [PATCH 32/59] Fix reexport-star inside of merged group --- .../crates/turbopack-ecmascript/src/references/esm/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 67d6b39d21897..68a3429e5ddae 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -159,7 +159,7 @@ impl ReferencedAsset { if let EcmascriptExports::EsmExports(exports) = *asset.get_exports().await? { - let exports = exports.await?; + let exports = exports.expand_exports(None).await?; let export = exports.exports.get(export); match export { Some(EsmExport::LocalBinding(name, _)) => { From f4f0f1acf5b537c75726f70a69707829bcb18d8b Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 16 May 2025 16:29:59 +0200 Subject: [PATCH 33/59] Fix local renaming when they are exports --- .../crates/turbopack-ecmascript/src/lib.rs | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 56c296c35d99b..8d133471fcbd9 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -109,7 +109,9 @@ use crate::{ merged_module::MergedEcmascriptModule, parse::generate_js_source_map, references::{ - analyse_ecmascript_module, async_module::OptionAsyncModule, esm::base::EsmAssetReferences, + analyse_ecmascript_module, + async_module::OptionAsyncModule, + esm::{base::EsmAssetReferences, export}, }, side_effect_optimization::reference::EcmascriptModulePartReference, simple_tree_shake::{ModuleExportUsageInfo, get_module_export_usages}, @@ -1059,7 +1061,7 @@ impl EcmascriptModuleContent { *generate_source_map, *original_source_map, *minify, - false, + None, ) .await?; emit_content(content, Default::default()).await @@ -1084,7 +1086,7 @@ impl EcmascriptModuleContent { generate_source_map, None, MinifyType::NoMinify, - false, + None, ) .await?; emit_content(content, Default::default()).await @@ -1172,7 +1174,7 @@ impl EcmascriptModuleContent { *generate_source_map, *original_source_map, *chunking_context.minify_type().await?, - true, + Some(is_export_mark), ) .await?, )) @@ -1243,6 +1245,7 @@ impl EcmascriptModuleContent { GLOBALS.set(&globals_merged, || { merged_ast .visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); + // merged_ast.visit_mut_with(&mut DisplayContextVisitor { postfix: "merged" }); }); merged_ast }; @@ -1281,7 +1284,7 @@ impl EcmascriptModuleContent { // postfix: &'static str, // } // impl VisitMut for DisplayContextVisitor { -// fn visit_mut_ident(&mut self, ident: &mut Ident) { +// fn visit_mut_ident(&mut self, ident: &mut swc_core::ecma::ast::Ident) { // ident.sym = format!("{}$$${}{}", ident.sym, self.postfix, ident.ctxt.as_u32()).into(); // } // } @@ -1314,7 +1317,7 @@ async fn process_parse_result( generate_source_map: bool, original_source_map: Option>>, minify: MinifyType, - retain_syntax_context: bool, + retain_syntax_context: Option, ) -> Result { let parsed = parsed.final_read_hint().await?; @@ -1385,8 +1388,11 @@ async fn process_parse_result( } GLOBALS.set(globals, || { - if retain_syntax_context { - program.visit_mut_with(&mut hygiene_rename_only(Some(top_level_mark))); + if let Some(is_export_mark) = retain_syntax_context { + program.visit_mut_with(&mut hygiene_rename_only( + Some(top_level_mark), + is_export_mark, + )); } else { program.visit_mut_with( &mut swc_core::ecma::transforms::base::hygiene::hygiene_with_config( @@ -1628,14 +1634,22 @@ fn process_content_with_code_gens( }; } -/// Like `hygiene`, but only renames the Atoms without clearing all SyntaxContexts -fn hygiene_rename_only(top_level_mark: Option) -> impl VisitMut { - struct HygieneRenamer; +/// Like `hygiene`, but only renames the Atoms without clearing all SyntaxContexts Don't rename +/// idents marked with `is_export_mark`: even if they are causing collisions, they will be handled +/// by the next hygiene pass over the whole module. +fn hygiene_rename_only(top_level_mark: Option, is_export_mark: Mark) -> impl VisitMut { + struct HygieneRenamer { + is_export_mark: Mark, + } impl swc_core::ecma::transforms::base::rename::Renamer for HygieneRenamer { const MANGLE: bool = false; const RESET_N: bool = true; fn new_name_for(&self, orig: &Id, n: &mut usize) -> Atom { + if orig.1.has_mark(self.is_export_mark) { + // Don't modify, it's an export + return orig.0.clone(); + } let res = if *n == 0 { orig.0.clone() } else { @@ -1650,7 +1664,7 @@ fn hygiene_rename_only(top_level_mark: Option) -> impl VisitMut { top_level_mark: top_level_mark.unwrap_or_default(), ..Default::default() }, - HygieneRenamer, + HygieneRenamer { is_export_mark }, ) } From efb5e95c03c54753d02e17c43cf8bf1513168e7d Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 19 May 2025 10:36:40 +0200 Subject: [PATCH 34/59] Fix local renaming when they are exports --- .../crates/turbopack-ecmascript/src/lib.rs | 77 ++++++++++++------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 8d133471fcbd9..6dd6e91a26430 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -49,6 +49,7 @@ use parse::{ParseResult, parse}; use path_visitor::ApplyVisitors; use references::esm::UrlRewriteBehavior; pub use references::{AnalyzeEcmascriptModuleResult, TURBOPACK_HELPER}; +use rustc_hash::FxHashSet; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; pub use static_code::StaticEcmascriptCode; @@ -1162,22 +1163,33 @@ impl EcmascriptModuleContent { module_syntax_contexts: &module_syntax_contexts, }; let code_gens = options.merged_code_gens(Some(ctx)).await?; - Ok(( - module, - module_syntax_contexts, - is_export_mark, - process_parse_result( - *parsed, - **ident, - *specified_module_type, - code_gens, - *generate_source_map, - *original_source_map, - *chunking_context.minify_type().await?, - Some(is_export_mark), - ) - .await?, - )) + let preserved_exports = match &*module.get_exports().await? { + EcmascriptExports::EsmExports(exports) => exports + .await? + .exports + .iter() + .flat_map(|(_, e)| { + if let export::EsmExport::LocalBinding(n, _) = e { + Some(Atom::from(&**n)) + } else { + None + } + }) + .collect(), + _ => Default::default(), + }; + let result = process_parse_result( + *parsed, + **ident, + *specified_module_type, + code_gens, + *generate_source_map, + *original_source_map, + *chunking_context.minify_type().await?, + Some((is_export_mark, preserved_exports)), + ) + .await?; + Ok((module, module_syntax_contexts, is_export_mark, result)) }) .try_join() .await?; @@ -1317,7 +1329,7 @@ async fn process_parse_result( generate_source_map: bool, original_source_map: Option>>, minify: MinifyType, - retain_syntax_context: Option, + retain_syntax_context: Option<(Mark, FxHashSet)>, ) -> Result { let parsed = parsed.final_read_hint().await?; @@ -1388,10 +1400,11 @@ async fn process_parse_result( } GLOBALS.set(globals, || { - if let Some(is_export_mark) = retain_syntax_context { + if let Some((is_export_mark, preserved_symbols)) = retain_syntax_context { program.visit_mut_with(&mut hygiene_rename_only( Some(top_level_mark), is_export_mark, + preserved_symbols, )); } else { program.visit_mut_with( @@ -1634,11 +1647,18 @@ fn process_content_with_code_gens( }; } -/// Like `hygiene`, but only renames the Atoms without clearing all SyntaxContexts Don't rename -/// idents marked with `is_export_mark`: even if they are causing collisions, they will be handled -/// by the next hygiene pass over the whole module. -fn hygiene_rename_only(top_level_mark: Option, is_export_mark: Mark) -> impl VisitMut { +/// Like `hygiene`, but only renames the Atoms without clearing all SyntaxContexts +/// +/// Don't rename idents marked with `is_export_mark` (i.e. imported identifier from another module) +/// or listed in `preserve_name` (i.e. export local binding): even if they are causing collisions, +/// they will be handled by the next hygiene pass over the whole module. +fn hygiene_rename_only( + top_level_mark: Option, + is_export_mark: Mark, + preserved_symbols: FxHashSet, +) -> impl VisitMut { struct HygieneRenamer { + preserved_symbols: FxHashSet, is_export_mark: Mark, } impl swc_core::ecma::transforms::base::rename::Renamer for HygieneRenamer { @@ -1646,10 +1666,6 @@ fn hygiene_rename_only(top_level_mark: Option, is_export_mark: Mark) -> im const RESET_N: bool = true; fn new_name_for(&self, orig: &Id, n: &mut usize) -> Atom { - if orig.1.has_mark(self.is_export_mark) { - // Don't modify, it's an export - return orig.0.clone(); - } let res = if *n == 0 { orig.0.clone() } else { @@ -1658,13 +1674,20 @@ fn hygiene_rename_only(top_level_mark: Option, is_export_mark: Mark) -> im *n += 1; res } + + fn preserve_name(&self, orig: &Id) -> bool { + self.preserved_symbols.contains(&orig.0) || orig.1.has_mark(self.is_export_mark) + } } swc_core::ecma::transforms::base::rename::renamer( swc_core::ecma::transforms::base::hygiene::Config { top_level_mark: top_level_mark.unwrap_or_default(), ..Default::default() }, - HygieneRenamer { is_export_mark }, + HygieneRenamer { + preserved_symbols, + is_export_mark, + }, ) } From 3dfb7d8f45f8840a9988dbcb49339b31c454f14f Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 19 May 2025 13:44:23 +0200 Subject: [PATCH 35/59] Refactor: MergeableModule.is_mergable --- .../crates/turbopack-core/src/chunk/mod.rs | 13 +- .../src/module_graph/merged_modules.rs | 182 +++++++++------ .../crates/turbopack-ecmascript/src/lib.rs | 221 ++++++++++-------- .../turbopack-ecmascript/src/merged_module.rs | 2 +- 4 files changed, 247 insertions(+), 171 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 16c20c31a1402..89d751ac7b9ed 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -124,9 +124,20 @@ impl MergeableModuleResult { } } +/// A [Module] that can be merged with other [Module]s (to perform scope hoisting) +// TODO currently this is only used for ecmascript modules, and with the current API cannot be used +// with other module types (as a MergeableModule cannot prevent itself from being mrerged with other +// arbitrary module types) #[turbo_tasks::value_trait] pub trait MergeableModule: Module + Asset { - fn merge(self: Vc, modules: Vc) -> Vc; + /// Even though MergeableModule is implemented, this allows a dynamic condition to determine + /// mergeability + fn is_mergeable(self: Vc) -> Vc { + Vc::cell(true) + } + + /// Create a new module representing the merged content of the given modules. + fn merge(self: Vc, modules: Vc) -> Vc>; } #[turbo_tasks::value(transparent)] pub struct MergeableModules(Vec<(ResolvedVc>, bool)>); diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 88e42ea50e791..0b3a8aa4fd117 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -5,7 +5,8 @@ use roaring::RoaringBitmap; use rustc_hash::{FxHashMap, FxHashSet}; use tracing::Instrument; use turbo_tasks::{ - FxIndexMap, FxIndexSet, ReadRef, ResolvedVc, SliceMap, TryJoinIterExt, ValueToString, Vc, + FxIndexMap, FxIndexSet, ResolvedVc, SliceMap, TryFlatJoinIterExt, TryJoinIterExt, + ValueToString, Vc, }; use crate::{ @@ -103,6 +104,24 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>(); + let mergeable = graphs + .iter() + .flat_map(|g| g.iter_nodes()) + .map(async |n| { + let module = n.module; + let mergeable = ResolvedVc::try_downcast::>(module); + if let Some(mergeable) = mergeable { + if *mergeable.is_mergeable().await? { + return Ok(Some(module)); + } + } + Ok(None) + }) + .try_flat_join() + .await? + .into_iter() + .collect::>(); + let visit_count = module_graph .traverse_edges_fixed_point_with_priority( entries.iter().map(|e| (*e, 0)), @@ -140,7 +159,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>(*m).is_some() }), - ResolvedVc::try_downcast::>(module).is_some(), + mergeable.contains(&module), hoisted, // TODO technically we could merge a sync child into an async parent !parent_module.is_some_and(|p| async_module_info.contains(&p)) @@ -287,76 +306,95 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>> = vec![]; - - let mut i = 0; - while i < list.len() - 1 { - let first = list[i]; - let modules = list[i..] - .iter() - .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) - .collect::>(); - match *first.merge(MergeableModules::interned(modules)).await? { - MergeableModuleResult::Merged { - merged_module, - consumed, - skipped, - } => { - // println!( - // "accepted from {:?} {:#?} {:?} consumed {} {:#?} skipped {} - // {:#?}", first.ident().to_string(). - // await?, list[i..] - // .iter() - // .map(|m| m.ident().to_string()) - // .try_join() - // .await?, - // merged_module.ident().to_string().await?, - // consumed, - // list.iter() - // .skip(i) - // .skip(skipped as usize) - // .take(consumed as usize) - // .map(|m| m.ident().to_string()) - // .try_join() - // .await?, - // skipped, - // list.iter() - // .skip(i) - // .take(skipped as usize) - // .map(|m| m.ident().to_string()) - // .try_join() - // .await?, - // ); - - let mut current_included = list[i..] - .iter() - .skip(skipped as usize) - .take(consumed as usize); - // The first module should not be `included` but `replaced` - let first = *current_included.next().unwrap(); - debug_assert!( - first.ident().to_string().await? - == merged_module.ident().to_string().await?, - "{} == {}", - first.ident().to_string().await?, - merged_module.ident().to_string().await? - ); - resulting_list.push(( - ResolvedVc::upcast::>(first), - merged_module, - )); - included.extend(current_included.copied().map(ResolvedVc::upcast)); - i += (skipped + consumed) as usize; - } - MergeableModuleResult::NotMerged => { - // None of them are mergeable. - return Ok(None); - } - } - } - - Ok(Some((resulting_list, included))) + let entry = *list.last().unwrap(); + + let list_exposed = list + .iter() + .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) + .collect::>(); + + let result = entry + .merge(MergeableModules::interned(list_exposed)) + .to_resolved() + .await?; + + let list_len = list.len(); + Ok(Some(( + [(ResolvedVc::upcast::>(entry), result)], + list.into_iter() + .take(list_len - 1) + .map(ResolvedVc::upcast) + .collect::>(), + ))) + + // let mut resulting_list = vec![]; + // let mut included: Vec>> = vec![]; + // let mut i = 0; + // while i < list.len() - 1 { + // let first = list[i]; + // let modules = list[i..] + // .iter() + // .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) + // .collect::>(); + // match *first.merge(MergeableModules::interned(modules)).await? { + // MergeableModuleResult::Merged { + // merged_module, + // consumed, + // skipped, + // } => { + // // println!( + // // "accepted from {:?} {:#?} {:?} consumed {} {:#?} skipped {} + // // {:#?}", first.ident().to_string(). + // // await?, list[i..] + // // .iter() + // // .map(|m| m.ident().to_string()) + // // .try_join() + // // .await?, + // // merged_module.ident().to_string().await?, + // // consumed, + // // list.iter() + // // .skip(i) + // // .skip(skipped as usize) + // // .take(consumed as usize) + // // .map(|m| m.ident().to_string()) + // // .try_join() + // // .await?, + // // skipped, + // // list.iter() + // // .skip(i) + // // .take(skipped as usize) + // // .map(|m| m.ident().to_string()) + // // .try_join() + // // .await?, + // // ); + + // let mut current_included = list[i..] + // .iter() + // .skip(skipped as usize) + // .take(consumed as usize); + // // The first module should not be `included` but `replaced` + // let first = *current_included.next().unwrap(); + // debug_assert!( + // first.ident().to_string().await? + // == merged_module.ident().to_string().await?, + // "{} == {}", + // first.ident().to_string().await?, + // merged_module.ident().to_string().await? + // ); + // resulting_list.push(( + // ResolvedVc::upcast::>(first), + // merged_module, + // )); + // included.extend(current_included.copied().map(ResolvedVc::upcast)); + // i += (skipped + consumed) as usize; + // } + // MergeableModuleResult::NotMerged => { + // // None of them are mergeable. + // return Ok(None); + // } + // } + // } + // Ok(Some((resulting_list, included))) }) .try_join() .await?; diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 6dd6e91a26430..aeb9dbedea5ed 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -41,7 +41,7 @@ use std::{ sync::Arc, }; -use anyhow::Result; +use anyhow::{Context, Result}; use chunk::EcmascriptChunkItem; use code_gen::{CodeGeneration, CodeGenerationHoistedStmt}; use either::Either; @@ -707,109 +707,136 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleAsset { #[turbo_tasks::value_impl] impl MergeableModule for EcmascriptModuleAsset { #[turbo_tasks::function] - async fn merge( - self: ResolvedVc, - modules: Vc, - ) -> Result> { - let modules = modules.await?; - - async fn is_eligible( - module: ResolvedVc>, - ) -> Result>>> { - if let Some(analyzable) = - ResolvedVc::try_sidecast::>(module) - { - if let Some(placeable) = - ResolvedVc::try_sidecast::>(module) - { - if matches!( - &*placeable.get_exports().await?, - |EcmascriptExports::DynamicNamespace| EcmascriptExports::CommonJs - | EcmascriptExports::EmptyCommonJs - | EcmascriptExports::Value - ) { - return Ok(None); - } - } - Ok(Some(analyzable)) - } else { - Ok(None) - } + async fn is_mergeable(self: ResolvedVc) -> Result> { + if matches!( + &*self.get_exports().await?, + EcmascriptExports::EsmExports(_) + ) { + return Ok(Vc::cell(true)); } - // let mut start_idx = None; - // let mut length = 0; - // for i in 0..modules.len() { - // let module = modules[i]; - // if let Some(module) = is_eligible(module).await? { - // if start_idx.is_some() { - // continue; - // } else { - // start_idx = Some(i); - // } - // } else { - // if let Some(start_idx) = start_idx - // && (i - start_idx) >= 2 + Ok(Vc::cell(false)) + } + + #[turbo_tasks::function] + async fn merge( + self: Vc, + modules: Vc, + ) -> Result>> { + Ok(Vc::upcast(*MergedEcmascriptModule::new( + modules + .await? + .iter() + .map(|(m, exposed)| { + Ok(( + ResolvedVc::try_sidecast::>(*m) + .context("expected EcmascriptAnalyzable")?, + *exposed, + )) + }) + .collect::>>()?, + self.options().to_resolved().await?, + ))) + + // let modules = modules.await?; + + // async fn is_eligible( + // module: ResolvedVc>, + // ) -> Result>>> { + // if let Some(analyzable) = + // ResolvedVc::try_sidecast::>(module) + // { + // if let Some(placeable) = + // ResolvedVc::try_sidecast::>(module) // { - // // We found a sequence of modules containing least 2 modules - // length = i - start_idx; - // break; - // } else { - // start_idx = None; + // if matches!( + // &*placeable.get_exports().await?, + // |EcmascriptExports::DynamicNamespace| EcmascriptExports::CommonJs + // | EcmascriptExports::EmptyCommonJs + // | EcmascriptExports::Value + // ) { + // return Ok(None); + // } // } + // Ok(Some(analyzable)) + // } else { + // Ok(None) // } // } - // let Some(start_idx) = start_idx else { - // return Ok(MergeableModuleResult::not_merged()); - // }; - // let consumed_modules = modules[start_idx..start_idx + length].to_vec(); - - let mut modules = modules.iter().zip(0u32..); - let mut merged_modules = vec![]; - let mut start_index = 0; - while let Some(((first, exposed), first_i)) = modules.next() { - // Skip some modules, try to find the first eligible module - if let Some(first) = is_eligible(*first).await? { - if merged_modules.is_empty() { - start_index = first_i; - } - merged_modules.push((first, *exposed)); - - // Consume as many modules as possible to merge together - for ((m, exposed), _) in &mut modules { - if let Some(m) = is_eligible(*m).await? { - merged_modules.push((m, *exposed)); - } else { - break; - } - } - // List has ended or incompatible module encountered - if merged_modules.len() > 1 { - // ... but we successfully found something to merge. - break; - } + // // let mut start_idx = None; + // // let mut length = 0; + // // for i in 0..modules.len() { + // // let module = modules[i]; + // // if let Some(module) = is_eligible(module).await? { + // // if start_idx.is_some() { + // // continue; + // // } else { + // // start_idx = Some(i); + // // } + // // } else { + // // if let Some(start_idx) = start_idx + // // && (i - start_idx) >= 2 + // // { + // // // We found a sequence of modules containing least 2 modules + // // length = i - start_idx; + // // break; + // // } else { + // // start_idx = None; + // // } + // // } + // // } + // // let Some(start_idx) = start_idx else { + // // return Ok(MergeableModuleResult::not_merged()); + // // }; + // // let consumed_modules = modules[start_idx..start_idx + length].to_vec(); + + // let mut modules = modules.iter().zip(0u32..); + // let mut merged_modules = vec![]; + // let mut start_index = 0; + // while let Some(((first, exposed), first_i)) = modules.next() { + // // Skip some modules, try to find the first eligible module + // if let Some(first) = is_eligible(*first).await? { + // if merged_modules.is_empty() { + // start_index = first_i; + // } + // merged_modules.push((first, *exposed)); + + // // Consume as many modules as possible to merge together + // for ((m, exposed), _) in &mut modules { + // if let Some(m) = is_eligible(*m).await? { + // merged_modules.push((m, *exposed)); + // } else { + // break; + // } + // } - // Only a single module, ignore and try to find a bigger sequence in the remaining - // list. - merged_modules.clear(); - } - } + // // List has ended or incompatible module encountered + // if merged_modules.len() > 1 { + // // ... but we successfully found something to merge. + // break; + // } - if merged_modules.len() > 1 { - Ok(MergeableModuleResult::Merged { - consumed: merged_modules.len() as u32, - skipped: start_index, - merged_module: ResolvedVc::upcast(MergedEcmascriptModule::new( - merged_modules, - // TODO where to get options from? - self.options().to_resolved().await?, - )), - } - .cell()) - } else { - Ok(MergeableModuleResult::not_merged()) - } + // // Only a single module, ignore and try to find a bigger sequence in the + // remaining // list. + // merged_modules.clear(); + // } + // } + + // if merged_modules.len() > 1 { + // Ok(MergeableModuleResult::Merged { + // consumed: merged_modules.len() as u32, + // skipped: start_index, + // merged_module: ResolvedVc::upcast(MergedEcmascriptModule::new( + // merged_modules, + // // TODO where to get options from? + // self.options().to_resolved().await?, + // )), + // } + // .cell()) + // } else { + // Ok(MergeableModuleResult::not_merged()) + // } } } @@ -1278,10 +1305,10 @@ impl EcmascriptModuleContent { .await?, extra_comments: SwcComments::default(), }; - let chunking_context = module_options.first().unwrap().await?.chunking_context; + let chunking_context = module_options.last().unwrap().await?.chunking_context; let additional_ids = modules .keys() - .skip(1) + .take(modules.len() - 1) .map(|m| m.chunk_item_id(*chunking_context).to_resolved()) .try_join() .await? diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs index 6684107bdd568..4a21174d945e8 100644 --- a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -43,7 +43,7 @@ impl Module for MergedEcmascriptModule { fn ident(&self) -> Vc { // This purposely reuses the module's ident as it has replaced the original module, thus // there can never be a collision. - self.modules.first().unwrap().0.ident() + self.modules.last().unwrap().0.ident() } #[turbo_tasks::function] From 87f0064d41b675be114f269c04aee2dc666b6ea1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 19 May 2025 18:10:43 +0200 Subject: [PATCH 36/59] Correct order of merged and unmerged references --- .../crates/turbopack-ecmascript/src/lib.rs | 200 ++++++++++++------ .../src/references/esm/base.rs | 70 +++--- 2 files changed, 176 insertions(+), 94 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index aeb9dbedea5ed..30c8f5edff8b1 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -62,7 +62,10 @@ use swc_core::{ util::take::Take, }, ecma::{ - ast::{self, Expr, Id, ModuleItem, Program, Script}, + ast::{ + self, CallExpr, Callee, EmptyStmt, Expr, ExprStmt, Id, ModuleItem, Program, Script, + Stmt, + }, codegen::{Emitter, text_writer::JsWriter}, visit::{VisitMut, VisitMutWith, VisitMutWithAstPath}, }, @@ -1221,73 +1224,9 @@ impl EcmascriptModuleContent { .try_join() .await?; - struct SetSyntaxContextVisitor<'a> { - current_module: ResolvedVc>, - // A marker to quickly identify the special cross-module variable references - export_mark: Mark, - // The syntax contexts in the merged AST (each module has its own) - merged_ctxts: - &'a FxIndexMap>, SyntaxContext>, - // The export syntax contexts in the current AST, which will be mapped to merged_ctxts - current_module_contexts: - &'a FxIndexMap>, SyntaxContext>, - } - impl VisitMut for SetSyntaxContextVisitor<'_> { - fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { - let module = if ctxt.has_mark(self.export_mark) { - *self - .current_module_contexts - .iter() - .find(|(_, module_ctxt)| *ctxt == **module_ctxt) - .unwrap() - .0 - } else { - self.current_module - }; - - *ctxt = *self.merged_ctxts.get(&module).unwrap(); - } - // fn visit_mut_span(&mut self, span: &mut Span) {} - } - // TODO properly merge ASTs: // - somehow merge the SourceMap struct - let merged_ast = { - let mut merged_ast = Program::Module(swc_core::ecma::ast::Module { - span: DUMMY_SP, - shebang: None, - body: contents - .into_iter() - .flat_map(|(module, module_contexts, export_mark, content)| { - if let CodeGenResult { - program: Program::Module(mut content), - globals, - .. - } = content - { - GLOBALS.set(&*globals, || { - content.visit_mut_with(&mut SetSyntaxContextVisitor { - current_module: module, - export_mark, - merged_ctxts: &merged_ctxts, - current_module_contexts: &module_contexts, - }); - }); - - content.body.clone() - } else { - unreachable!() - } - }) - .collect(), - }); - GLOBALS.set(&globals_merged, || { - merged_ast - .visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); - // merged_ast.visit_mut_with(&mut DisplayContextVisitor { postfix: "merged" }); - }); - merged_ast - }; + let merged_ast = merge_modules(contents, &merged_ctxts, &globals_merged).await?; let content = CodeGenResult { program: merged_ast, source_map: Arc::new(SourceMap::default()), @@ -1319,6 +1258,135 @@ impl EcmascriptModuleContent { } #[allow(clippy::type_complexity)] +async fn merge_modules( + mut contents: Vec<( + ResolvedVc>, + FxIndexMap>, SyntaxContext>, + Mark, + CodeGenResult, + )>, + merged_ctxts: &'_ FxIndexMap>, SyntaxContext>, + globals_merged: &'_ Globals, +) -> Result { + struct SetSyntaxContextVisitor<'a> { + current_module: ResolvedVc>, + // A marker to quickly identify the special cross-module variable references + export_mark: Mark, + // The syntax contexts in the merged AST (each module has its own) + merged_ctxts: &'a FxIndexMap>, SyntaxContext>, + // The export syntax contexts in the current AST, which will be mapped to merged_ctxts + current_module_contexts: + &'a FxIndexMap>, SyntaxContext>, + } + impl VisitMut for SetSyntaxContextVisitor<'_> { + fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { + let module = if ctxt.has_mark(self.export_mark) { + *self + .current_module_contexts + .iter() + .find(|(_, module_ctxt)| *ctxt == **module_ctxt) + .unwrap() + .0 + } else { + self.current_module + }; + + *ctxt = *self.merged_ctxts.get(&module).unwrap(); + } + // fn visit_mut_span(&mut self, span: &mut Span) {} + } + + let prepare_module = |(module, module_contexts, export_mark, content): &mut ( + ResolvedVc>, + FxIndexMap>, SyntaxContext>, + Mark, + CodeGenResult, + )| { + if let CodeGenResult { + program: Program::Module(content), + globals, + .. + } = content + { + GLOBALS.set(&*globals, || { + content.visit_mut_with(&mut SetSyntaxContextVisitor { + current_module: *module, + export_mark: *export_mark, + merged_ctxts, + current_module_contexts: module_contexts, + }); + }); + + content.take().body + } else { + unreachable!() + } + }; + + let mut inserted = FxHashSet::with_capacity_and_hasher(contents.len(), Default::default()); + inserted.insert(contents.len() - 1); + + let mut merged_ast = swc_core::ecma::ast::Module { + span: DUMMY_SP, + shebang: None, + body: prepare_module(contents.last_mut().unwrap()), + }; + + // Replace inserted `__turbopack_merged_esm__(i);` statements with the corresponding ith-module + let mut i = 0; + loop { + if i >= merged_ast.body.len() { + break; + } + if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) = &merged_ast.body[i] { + if let Expr::Call(CallExpr { + callee: Callee::Expr(callee), + args, + .. + }) = &**expr + { + if callee.is_ident_ref_to("__turbopack_merged_esm__") { + let index = args[0].expr.as_lit().unwrap().as_num().unwrap().value as usize; + + if inserted.insert(index) { + let module = &mut contents[index]; + merged_ast.body.splice(i..=i, prepare_module(module)); + + // Don't increment, the ith item has just changed + continue; + } else { + // Already inserted (and thus already executed), remove the placeholder + merged_ast.body[i] = + ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP })); + } + } + } + } + + i += 1; + } + + debug_assert!( + inserted.len() == contents.len(), + "Not all merged modules were inserted: {:?}", + contents + .iter() + .enumerate() + .map(async |(i, m)| Ok((inserted.contains(&i), m.0.ident().to_string().await?))) + .try_join() + .await?, + ); + + let mut merged_ast = Program::Module(merged_ast); + + GLOBALS.set(globals_merged, || { + merged_ast.visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); + // merged_ast.visit_mut_with(&mut DisplayContextVisitor { postfix: "merged" }); + }); + + Ok(merged_ast) +} + // struct DisplayContextVisitor { // postfix: &'static str, // } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 68a3429e5ddae..99037747405b3 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -39,7 +39,7 @@ use crate::{ ScopeHoistingContext, TreeShakingMode, analyzer::imports::ImportAnnotations, chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, - code_gen::CodeGeneration, + code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, magic_identifier, references::{ esm::EsmExport, @@ -479,7 +479,7 @@ impl EsmAssetReference { let this = &*self.await?; // only chunked references can be imported - let result = if this.annotations.chunking_type() != Some("none") { + if this.annotations.chunking_type() != Some("none") { let import_externals = this.import_externals; let referenced_asset = self.get_referenced_asset().await?; @@ -492,22 +492,43 @@ impl EsmAssetReference { expr: Box::new(throw_module_not_found_expr(&request)), span: DUMMY_SP, }); - Some((format!("throw {request}").into(), stmt)) + return Ok(CodeGeneration::hoisted_stmt( + format!("throw {request}").into(), + stmt, + )); } - ReferencedAsset::None => None, + ReferencedAsset::None => {} _ => { - if let ReferencedAsset::Some(asset) = &*referenced_asset - && scope_hoisting_context - .is_some_and(|c| c.modules.contains_key(&ResolvedVc::upcast(*asset))) + let mut result = vec![]; + + let merged_index = scope_hoisting_context + .zip(if let ReferencedAsset::Some(asset) = &*referenced_asset { + Some(*asset) + } else { + None + }) + .and_then(|(c, asset)| c.modules.get_index_of(&ResolvedVc::upcast(asset))); + + if let Some(merged_index) = merged_index { + // Insert a placeholder to inline the merged module at the right place + // relative to the other references (so to keep reference order). + result.push(CodeGenerationHoistedStmt::new( + format!("hoisted {merged_index}").into(), + quote!( + "__turbopack_merged_esm__($id);" as Stmt, + id: Expr = Lit::Num(merged_index.into()).into(), + ), + )); + } + + if merged_index.is_some() && !this .export_name .as_ref() .is_none_or(|e| matches!(e, ModulePart::Exports)) { // No need to import, the module is already available in the same scope - // hoisting group. - // And it's not requiring a namespace import, - None + // hoisting group (unless it's a namespace import) } else if let Some(ident) = referenced_asset .get_ident(chunking_context, None, scope_hoisting_context) .await? @@ -521,12 +542,12 @@ impl EsmAssetReference { }); match &*referenced_asset { ReferencedAsset::Unresolvable => { - unreachable!() + unreachable!(); } ReferencedAsset::Some(asset) => { let id = asset.chunk_item_id(Vc::upcast(chunking_context)).await?; let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( + result.push(CodeGenerationHoistedStmt::new( id.to_string().into(), var_decl_with_span( quote!( @@ -537,7 +558,7 @@ impl EsmAssetReference { ), span, ), - )) + )); } ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => { if !*chunking_context @@ -553,7 +574,7 @@ impl EsmAssetReference { ); } let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( + result.push(CodeGenerationHoistedStmt::new( name.sym.as_str().into(), var_decl_with_span( if import_externals { @@ -573,7 +594,7 @@ impl EsmAssetReference { }, span, ), - )) + )); } ReferencedAsset::External( request, @@ -592,7 +613,7 @@ impl EsmAssetReference { ); } let name = ident.as_expr_individual(DUMMY_SP).unwrap_left(); - Some(( + result.push(CodeGenerationHoistedStmt::new( name.sym.as_str().into(), var_decl_with_span( quote!( @@ -603,7 +624,7 @@ impl EsmAssetReference { ), span, ), - )) + )); } // fallback in case we introduce a new `ExternalType` #[allow(unreachable_patterns)] @@ -615,22 +636,15 @@ impl EsmAssetReference { request ) } - ReferencedAsset::None => None, - } - } else { - None + ReferencedAsset::None => {} + }; } + return Ok(CodeGeneration::hoisted_stmts(result)); } } - } else { - None }; - if let Some((key, stmt)) = result { - Ok(CodeGeneration::hoisted_stmt(key, stmt)) - } else { - Ok(CodeGeneration::empty()) - } + Ok(CodeGeneration::empty()) } } From 9309963429649c69fda836e5b65b126cf9df9159 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 20 May 2025 14:19:00 +0200 Subject: [PATCH 37/59] Fix list traversal with cycles --- .../src/module_graph/merged_modules.rs | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 0b3a8aa4fd117..26a54deabb483 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -254,12 +254,23 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>> = FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + let mut visited = FxHashSet::default(); module_graph .traverse_edges_from_entries_topological( - entries, + entries.iter().copied(), &mut (), - |_, _, _| Ok(GraphTraversalAction::Continue), - |parent_info, node, _| { + |_, node, _| { + // This is necessary to have the correct order with cycles: a `a -> b -> a` + // graph would otherwise be visited as `b->a`, `a->b`, + // leading to the list `a, b` which is not execution order. + + if visited.insert(node.module) { + Ok(GraphTraversalAction::Continue) + } else { + Ok(GraphTraversalAction::Exclude) + } + }, + |_, node, _| { let module = node.module; if let Some(mergeable_module) = @@ -273,6 +284,19 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result Date: Wed, 21 May 2025 13:52:38 +0200 Subject: [PATCH 38/59] Ensure correct ordering --- .../src/module_graph/merged_modules.rs | 412 +++++++++++++++--- 1 file changed, 355 insertions(+), 57 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 26a54deabb483..6e5cdcb3fa9a1 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -1,6 +1,6 @@ -use std::collections::hash_map::Entry; +use std::{cmp::Ordering, collections::hash_map::Entry}; -use anyhow::Result; +use anyhow::{Context, Result, bail}; use roaring::RoaringBitmap; use rustc_hash::{FxHashMap, FxHashSet}; use tracing::Instrument; @@ -71,6 +71,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result) -> Result>(); + let mut next_index = 0u32; let visit_count = module_graph .traverse_edges_fixed_point_with_priority( entries.iter().map(|e| (*e, 0)), @@ -244,52 +244,167 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>>, - > = FxIndexMap::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + #[derive(Debug, PartialEq, Eq, Hash)] + struct ListOccurence { + list: usize, + entry: usize, + } + impl PartialOrd for ListOccurence { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + impl Ord for ListOccurence { + fn cmp(&self, other: &Self) -> Ordering { + self.entry + .cmp(&other.entry) + // don't matter but needed to make it a total ordering + .then_with(|| self.list.cmp(&other.list)) + } + } + + // A list of all different execution traces (orders) of all modules, initially a union of + // the partition of each chunk's modules (one for each ESM subtree in each chunks), but + // further split up later on. + let mut lists = FxIndexSet::default(); + let mut lists_reverse_indices: FxIndexMap< + ResolvedVc>, + FxIndexSet, + > = FxIndexMap::default(); + + // TODO try to parallelize this loop somehow + for chunk_group in &chunk_group_info.chunk_groups { + // A partition of all modules in the chunk into several execution traces (orders), + // stored in the top-level lists and referenced here by index. + let mut chunk_lists: FxHashMap = + FxHashMap::with_capacity_and_hasher( + module_merged_groups.len() / chunk_group_info.chunk_groups.len(), + Default::default(), + ); + + // This is necessary to have the correct order with cycles: a `a -> b -> a` graph would + // otherwise be visited as `b->a`, `a->b`, leading to the list `a, b` which is not + // execution order. + let mut visited = FxHashSet::default(); + + module_graph + .traverse_edges_from_entries_topological( + chunk_group.entries(), + &mut (), + |parent_info, node, _| { + if parent_info.is_none_or(|(_, r)| r.chunking_type.is_parallel()) + && visited.insert(node.module) + { + Ok(GraphTraversalAction::Continue) + } else { + Ok(GraphTraversalAction::Exclude) + } + }, + |_parent_info, node, _| { + let module = node.module; + + if let Some(bitmap) = module_merged_groups.get(&module) { + if let Some(mergeable_module) = + ResolvedVc::try_downcast::>(module) + { + match chunk_lists.entry(bitmap.clone()) { + Entry::Vacant(e) => { + // New list, insert the module + let idx = lists.len(); + e.insert(idx); + lists.insert(vec![mergeable_module]); + lists_reverse_indices + .entry(mergeable_module) + .or_default() + .insert(ListOccurence { + list: idx, + entry: 0, + }); + } + Entry::Occupied(e) => { + let list_idx = *e.get(); + let list = lists.get_index_mut2(list_idx).unwrap(); + list.push(mergeable_module); + lists_reverse_indices + .entry(mergeable_module) + .or_default() + .insert(ListOccurence { + list: list_idx, + entry: list.len() - 1, + }); + } + } + } + } + }, + ) + .await?; + + // println!( + // "lists {:#?}", + // chunk_lists + // .iter() + // .map(async |(b, l)| Ok(( + // b, + // lists[*l] + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await? + // ))) + // .try_join() + // .await? + // ); + } + + // TODO sort lists_reverse_indices somehow? + // We use list.pop() below, so reverse order using negation + lists_reverse_indices + .sort_by_cached_key(|_, b| b.iter().map(|o| o.entry).min().map(|v| -(v as i64))); + + // println!( + // "lists {:#?}", + // lists + // .iter() + // .map(|m| m.iter().map(|m| m.ident().to_string()).try_join()) + // .try_join() + // .await?, + // // lists + // // .iter() + // // .filter(|(_, v)| v.len() > 1) + // // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // // .try_join() + // // .await? + // ); + + // println!( + // "lists_reverse_indices {:#?}", + // lists_reverse_indices + // .iter() + // .map(async |(m, l)| Ok((m.ident().to_string().await?, l))) + // .try_join() + // .await?, + // // lists + // // .iter() + // // .filter(|(_, v)| v.len() > 1) + // // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // // .try_join() + // // .await? + // ); + // Modules that are referenced from outside the group, so their exports need to be exposed. let mut exposed_modules: FxHashSet>> = FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); - let mut visited = FxHashSet::default(); - module_graph - .traverse_edges_from_entries_topological( - entries.iter().copied(), - &mut (), - |_, node, _| { - // This is necessary to have the correct order with cycles: a `a -> b -> a` - // graph would otherwise be visited as `b->a`, `a->b`, - // leading to the list `a, b` which is not execution order. - - if visited.insert(node.module) { - Ok(GraphTraversalAction::Continue) - } else { - Ok(GraphTraversalAction::Exclude) - } - }, - |_, node, _| { - let module = node.module; - - if let Some(mergeable_module) = - ResolvedVc::try_downcast::>(module) - { - let bitmap = module_merged_groups - .get(&module) - .expect("Module should be in the map"); - lists - .entry(bitmap.clone()) - .or_default() - .insert(mergeable_module); - } - }, - ) - .await?; + // A map of all references inside of merged groups, if both modules have the same bitmap + // (and thus are in the same group, unless they are further split up below). + let mut intra_group_references: FxIndexMap< + ResolvedVc>, + FxIndexSet>>, + > = FxIndexMap::default(); - // TODO ideally this would be done in the previous traversal, but we need to traverse all - // edges here, which screws up the order for `lists` + // These have to be exposed, but we might need to expose more modules if the lists are split + // up further below. module_graph .traverse_edges_from_entries_topological( entries, @@ -298,32 +413,215 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>(), ); + + // Split into three lists: + // - "common" [occurrence.entry .. occurrence.entry + common_length) -- same for all + // - "before" [0 .. occurrence.entry) + // - "after" [occurrence.entry + common_length .. ] + let common_list = lists[first_occurence.list] + [first_occurence.entry..first_occurence.entry + common_length] + .to_vec(); + + let (common_list_index, _) = lists.insert_full(common_list.clone()); + + // Insert occurences for the "common" list, skip the first because that is now + // guaranteed to exist only once + for (i, &m) in common_list.iter().enumerate().skip(1) { + let occurrences = lists_reverse_indices.get_mut(&m).unwrap(); + for common_occurrence in &common_occurences { + let removed = occurrences.swap_remove(&ListOccurence { + list: common_occurrence.list, + entry: common_occurrence.entry + i, + }); + debug_assert!(removed); + } + occurrences.insert(ListOccurence { + list: common_list_index, + entry: i, + }); + } + + for common_occurrence in &common_occurences { + let list = lists.get_index_mut2(common_occurrence.list).unwrap(); + let after_list = list.split_off(common_occurrence.entry + common_length); + list.truncate(common_occurrence.entry); + let before_list = &*list; + + // For all references that exist from "after" to "common" and from "common" to + // "before", mark the referenced modules as exposed. + // for m in &common_list { + // let m = ResolvedVc::upcast(*m); + // if let Some(refs) = intra_group_references.get(&m) { + // exposed_modules.extend( + // before_list + // .iter() + // .map(|n| ResolvedVc::upcast(*n)) + // .filter(|n| refs.contains(n)), + // ); + // } + // } + // for m in &after_list { + // let m = ResolvedVc::upcast(*m); + // if let Some(refs) = intra_group_references.get(&m) { + // exposed_modules.extend( + // common_list + // .iter() + // .map(|n| ResolvedVc::upcast(*n)) + // .filter(|n| refs.contains(n)), + // ); + // } + // } + + // println!( + // "{} {:#?} {:#?} {:#?}", + // common_length, + // list.iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // common_list + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // after_list + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await? + // ); + + // The occurences for the "before" list (`list`) are still valid, need to update the + // occurences for the "after" list + let (after_index, _) = lists.insert_full(after_list.clone()); + for (i, &m) in after_list.iter().enumerate() { + let occurrences = lists_reverse_indices + .get_mut(&m) + .context(format!("{:?}", m.ident().to_string().await?))?; + + let removed = occurrences.swap_remove(&ListOccurence { + list: common_occurrence.list, + entry: common_occurrence.entry + common_length + i, + }); + debug_assert!(removed); + + occurrences.insert(ListOccurence { + list: after_index, + entry: i, + }); + } + } + } + // println!( // "lists {:#?}", // lists // .iter() - // .filter(|(_, v)| v.len() > 1) - // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // .map(|m| m.iter().map(|m| m.ident().to_string()).try_join()) // .try_join() - // .await? + // .await?, + // // lists + // // .iter() + // // .filter(|(_, v)| v.len() > 1) + // // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // // .try_join() + // // .await? + // ); + // println!( + // "exposed_modules {:#?}", + // exposed_modules + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // // lists + // // .iter() + // // .filter(|(_, v)| v.len() > 1) + // // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // // .try_join() + // // .await? + // ); + + // println!( + // "lists_reverse_indices {:#?}", + // lists_reverse_indices + // .iter() + // .map(async |(m, l)| Ok((m.ident().to_string().await?, l))) + // .try_join() + // .await?, + // // lists + // // .iter() + // // .filter(|(_, v)| v.len() > 1) + // // .map(|(_, l)| l.iter().map(|m| m.ident().to_string()).try_join()) + // // .try_join() + // // .await? // ); // Call MergeableModule impl to merge the modules (or not, if they are rejected). let result = lists - .into_values() + .into_iter() .map(async |list| { if list.len() < 2 { // Nothing to merge From d304029a996521c83975c5e469a8d5c6ca5f89a5 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 14:49:38 +0200 Subject: [PATCH 39/59] Multiple entries in a merged group --- .../crates/turbopack-core/src/chunk/mod.rs | 19 +++- .../src/module_graph/merged_modules.rs | 90 ++++++++++++------- .../crates/turbopack-ecmascript/src/lib.rs | 34 +++++-- .../turbopack-ecmascript/src/merged_module.rs | 16 +++- 4 files changed, 118 insertions(+), 41 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 89d751ac7b9ed..2ec304dda3693 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -137,13 +137,28 @@ pub trait MergeableModule: Module + Asset { } /// Create a new module representing the merged content of the given modules. - fn merge(self: Vc, modules: Vc) -> Vc>; + fn merge( + self: Vc, + modules: Vc, + entries: Vc, + ) -> Vc>; } #[turbo_tasks::value(transparent)] -pub struct MergeableModules(Vec<(ResolvedVc>, bool)>); +pub struct MergeableModules(Vec>>); #[turbo_tasks::value_impl] impl MergeableModules { + #[turbo_tasks::function] + pub fn interned(modules: Vec>>) -> Vc { + Vc::cell(modules) + } +} + +#[turbo_tasks::value(transparent)] +pub struct MergeableModulesExposed(Vec<(ResolvedVc>, bool)>); + +#[turbo_tasks::value_impl] +impl MergeableModulesExposed { #[turbo_tasks::function] pub fn interned(modules: Vec<(ResolvedVc>, bool)>) -> Vc { Vc::cell(modules) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 6e5cdcb3fa9a1..1fd73ae5604cf 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -11,7 +11,7 @@ use turbo_tasks::{ use crate::{ chunk::{ - ChunkableModule, ChunkingType, MergeableModule, MergeableModuleResult, MergeableModules, + ChunkableModule, ChunkingType, MergeableModule, MergeableModules, MergeableModulesExposed, }, module::Module, module_graph::{ @@ -396,12 +396,17 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>> = FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); - // A map of all references inside of merged groups, if both modules have the same bitmap - // (and thus are in the same group, unless they are further split up below). + // A map of all references inside of merged groups, if both + // modules have the same bitmap (and thus are in the same group, unless they are further + // split up below). let mut intra_group_references: FxIndexMap< ResolvedVc>, FxIndexSet>>, > = FxIndexMap::default(); + let mut intra_group_references_rev: FxIndexMap< + ResolvedVc>, + FxIndexSet>>, + > = FxIndexMap::default(); // These have to be exposed, but we might need to expose more modules if the lists are split // up further below. @@ -425,9 +430,13 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result) -> Result>(m)) + .collect::>(); + + // Group entries are not referenced by any other module in the group + let entries = list + .iter() + .filter(|m| { + intra_group_references_rev + .get(&ResolvedVc::upcast(**m)) + .is_none_or(|refs| refs.is_disjoint(&list_set)) + }) + .map(|m| **m) + .collect::>(); let list_exposed = list .iter() .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) .collect::>(); + let entry = *list.last().unwrap(); let result = entry - .merge(MergeableModules::interned(list_exposed)) + .merge( + MergeableModulesExposed::interned(list_exposed), + MergeableModules::interned(entries), + ) .to_resolved() .await?; diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 30c8f5edff8b1..6f10cb058b4e4 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -86,8 +86,8 @@ use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, - MergeableModule, MergeableModuleResult, MergeableModules, MinifyType, ModuleChunkItemIdExt, - ModuleId, + MergeableModule, MergeableModules, MergeableModulesExposed, MinifyType, + ModuleChunkItemIdExt, ModuleId, }, compile_time_info::CompileTimeInfo, context::AssetContext, @@ -724,7 +724,8 @@ impl MergeableModule for EcmascriptModuleAsset { #[turbo_tasks::function] async fn merge( self: Vc, - modules: Vc, + modules: Vc, + entries: Vc, ) -> Result>> { Ok(Vc::upcast(*MergedEcmascriptModule::new( modules @@ -738,6 +739,14 @@ impl MergeableModule for EcmascriptModuleAsset { )) }) .collect::>>()?, + entries + .await? + .iter() + .map(|m| { + ResolvedVc::try_sidecast::>(*m) + .context("expected EcmascriptAnalyzable") + }) + .collect::>>()?, self.options().to_resolved().await?, ))) @@ -1129,6 +1138,7 @@ impl EcmascriptModuleContent { pub async fn new_merged( modules: Vec<(ResolvedVc>, bool)>, module_options: Vec>, + entries: Vec>>, ) -> Result> { let modules = modules .into_iter() @@ -1139,6 +1149,13 @@ impl EcmascriptModuleContent { ) }) .collect::>(); + let entries = entries + .into_iter() + .map(|m| { + let m = ResolvedVc::try_sidecast::>(m).unwrap(); + (m, modules.get_index_of(&m).unwrap()) + }) + .collect::>(); let globals_merged = Globals::default(); let merged_ctxts = GLOBALS.set(&globals_merged, || { @@ -1226,7 +1243,7 @@ impl EcmascriptModuleContent { // TODO properly merge ASTs: // - somehow merge the SourceMap struct - let merged_ast = merge_modules(contents, &merged_ctxts, &globals_merged).await?; + let merged_ast = merge_modules(contents, entries, &merged_ctxts, &globals_merged).await?; let content = CodeGenResult { program: merged_ast, source_map: Arc::new(SourceMap::default()), @@ -1265,6 +1282,7 @@ async fn merge_modules( Mark, CodeGenResult, )>, + entries: Vec<(ResolvedVc>, usize)>, merged_ctxts: &'_ FxIndexMap>, SyntaxContext>, globals_merged: &'_ Globals, ) -> Result { @@ -1324,12 +1342,16 @@ async fn merge_modules( }; let mut inserted = FxHashSet::with_capacity_and_hasher(contents.len(), Default::default()); - inserted.insert(contents.len() - 1); + + inserted.extend(entries.iter().map(|(_, i)| *i)); let mut merged_ast = swc_core::ecma::ast::Module { span: DUMMY_SP, shebang: None, - body: prepare_module(contents.last_mut().unwrap()), + body: entries + .iter() + .flat_map(|(_, i)| prepare_module(&mut contents[*i])) + .collect(), }; // Replace inserted `__turbopack_merged_esm__(i);` statements with the corresponding ith-module diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs index 4a21174d945e8..645a42c5f9dca 100644 --- a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -17,15 +17,22 @@ use crate::{ #[turbo_tasks::value(shared)] pub(crate) struct MergedEcmascriptModule { modules: Vec<(ResolvedVc>, bool)>, + entries: Vec>>, options: ResolvedVc, } impl MergedEcmascriptModule { pub fn new( modules: Vec<(ResolvedVc>, bool)>, + entries: Vec>>, options: ResolvedVc, ) -> ResolvedVc { - MergedEcmascriptModule { modules, options }.resolved_cell() + MergedEcmascriptModule { + modules, + entries, + options, + } + .resolved_cell() } } @@ -122,6 +129,7 @@ impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { ) -> Result> { let module = self.module.await?; let modules = &module.modules; + let entries = &module.entries; // println!( // "merged chunk item: {:?}", // modules @@ -144,7 +152,11 @@ impl EcmascriptChunkItem for MergedEcmascriptModuleChunkItem { }) .collect::>>()?; - let content = EcmascriptModuleContent::new_merged(modules.clone(), options); + let content = EcmascriptModuleContent::new_merged( + modules.clone(), + options, + entries.iter().map(|m| **m).collect(), + ); // TODO async let async_module_options = Vc::cell(None); From 9fc14c14fbcec67a88f53ba32cd79145becda927 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 15:55:57 +0200 Subject: [PATCH 40/59] Correctly compute merged group entries --- .../src/module_graph/merged_modules.rs | 192 +++++++++++------- 1 file changed, 119 insertions(+), 73 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 1fd73ae5604cf..53c4e1f7d8810 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -266,12 +266,26 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>, FxIndexSet, > = FxIndexMap::default(); + // A map of all references inside of merged groups, if both modules have the same bitmap + // (and thus are in the same group, unless they are further split up below). + // These are only the references relevant for execution (ignoring cycles) + #[allow(clippy::type_complexity)] + let mut intra_group_references: FxIndexMap< + ResolvedVc>, + FxIndexSet>>, + > = FxIndexMap::default(); + #[allow(clippy::type_complexity)] + let mut intra_group_references_rev: FxIndexMap< + ResolvedVc>, + FxIndexSet>>, + > = FxIndexMap::default(); + // TODO try to parallelize this loop somehow for chunk_group in &chunk_group_info.chunk_groups { // A partition of all modules in the chunk into several execution traces (orders), @@ -300,7 +314,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result) -> Result { let list_idx = *e.get(); - let list = lists.get_index_mut2(list_idx).unwrap(); + let list = &mut lists[list_idx]; list.push(mergeable_module); lists_reverse_indices .entry(mergeable_module) @@ -336,6 +350,22 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result>> = + FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); + // These have to be exposed, but we might need to expose more modules if the lists are split + // up further below. + module_graph + .traverse_edges_from_entries_topological( + entries, + &mut (), + |_, _, _| Ok(GraphTraversalAction::Continue), + |parent_info, node, _| { + let module = node.module; + + if let Some((parent, r)) = parent_info { + let same_bitmap = module_merged_groups.get(&parent.module).unwrap() + == module_merged_groups.get(&module).unwrap(); + + if !same_bitmap || matches!(r.export, ExportUsage::All) { + // A reference from another group or a namespace import, this module + // needs to be exposed. + exposed_modules.insert(module); + } + } + }, + ) + .await?; + // println!( // "lists {:#?}", // lists @@ -392,63 +449,12 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>> = - FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); - - // A map of all references inside of merged groups, if both - // modules have the same bitmap (and thus are in the same group, unless they are further - // split up below). - let mut intra_group_references: FxIndexMap< - ResolvedVc>, - FxIndexSet>>, - > = FxIndexMap::default(); - let mut intra_group_references_rev: FxIndexMap< - ResolvedVc>, - FxIndexSet>>, - > = FxIndexMap::default(); - - // These have to be exposed, but we might need to expose more modules if the lists are split - // up further below. - module_graph - .traverse_edges_from_entries_topological( - entries, - &mut (), - |_, _, _| Ok(GraphTraversalAction::Continue), - |parent_info, node, _| { - let module = node.module; - - if let Some((parent, r)) = parent_info { - let same_bitmap = module_merged_groups.get(&parent.module).unwrap() - == module_merged_groups.get(&module).unwrap(); - - if !same_bitmap || matches!(r.export, ExportUsage::All) { - // A reference from another group or a namespace import, this module - // needs to be exposed. - exposed_modules.insert(module); - } - - if !same_bitmap { - intra_group_references - .entry(module) - .or_default() - .insert(parent.module); - intra_group_references_rev - .entry(module) - .or_default() - .insert(parent.module); - } - } - }, - ) - .await?; - while let Some((_, common_occurences)) = lists_reverse_indices.pop() { - // println!("{:?} {:?}", m.ident().to_string().await?, common_occurences); if common_occurences.len() < 2 { // Module exists only in one list, no need to split continue; } + // println!("{:?} {:?}", m.ident().to_string().await?, common_occurences); // The module occurs in multiple lists, which need to split up so that there is exactly // one list containing the module. @@ -493,7 +499,8 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result) -> Result) -> Result>(); + // Call MergeableModule impl to merge the modules (or not, if they are rejected). let result = lists .into_iter() @@ -653,12 +666,45 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>(); + debug_assert_ne!(entries.len(), 0); let list_exposed = list .iter() .map(|&m| (m, exposed_modules.contains(&ResolvedVc::upcast(m)))) .collect::>(); + // println!( + // "merged {:#?} {:#?} {:#?}", + // list.iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await?, + // list.iter() + // .map(async |m| { + // Ok( + // if let Some(refs) = + // intra_group_references_rev.get(&ResolvedVc::upcast(*m)) + // { + // Some( + // refs.iter() + // .map(|r| r.ident().to_string()) + // .try_join() + // .await?, + // ) + // } else { + // None + // }, + // ) + // }) + // .try_join() + // .await?, + // entries + // .iter() + // .map(|m| m.ident().to_string()) + // .try_join() + // .await? + // ); + let entry = *list.last().unwrap(); let result = entry .merge( From 68e9633e1f6f6f5d05342bfb98955f851af80f6c Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 May 2025 17:01:08 +0200 Subject: [PATCH 41/59] Expose entry modules (assuming they are required) --- .../src/module_graph/merged_modules.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 53c4e1f7d8810..9dea309551dd5 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -405,15 +405,17 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result Date: Wed, 21 May 2025 18:20:00 +0200 Subject: [PATCH 42/59] is_module_merging_enabled on context, not in dev --- crates/next-core/src/next_client/context.rs | 36 +++--- crates/next-core/src/next_edge/context.rs | 60 ++++----- crates/next-core/src/next_server/context.rs | 6 +- .../turbopack-browser/src/chunking_context.rs | 13 ++ .../crates/turbopack-cli/src/build/mod.rs | 70 ++++++----- .../turbopack-core/src/chunk/chunk_group.rs | 117 ++++++++++-------- .../src/chunk/chunking_context.rs | 7 ++ .../turbopack-nodejs/src/chunking_context.rs | 13 ++ .../crates/turbopack-tests/tests/execution.rs | 1 + 9 files changed, 188 insertions(+), 135 deletions(-) diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index b5b0532572b78..b0a61f72d5018 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -473,23 +473,25 @@ pub async fn get_client_chunking_context( if next_mode.is_development() { builder = builder.hot_module_replacement().use_file_source_map_uris(); } else { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 50_000, - max_chunk_count_per_group: 40, - max_merge_chunk_size: 200_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); - builder = builder.use_content_hashing(ContentHashing::Direct { length: 16 }) + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 50_000, + max_chunk_count_per_group: 40, + max_merge_chunk_size: 200_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .use_content_hashing(ContentHashing::Direct { length: 16 }) + .module_merging(true); } Ok(Vc::upcast(builder.build())) diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index 7179aab11723d..12df8bee1802d 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -255,20 +255,22 @@ pub async fn get_edge_chunking_context_with_client_assets( .module_id_strategy(module_id_strategy); if !next_mode.is_development() { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 20_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 20_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .module_merging(true); } Ok(Vc::upcast(builder.build())) @@ -318,20 +320,22 @@ pub async fn get_edge_chunking_context( .module_id_strategy(module_id_strategy); if !next_mode.is_development() { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 20_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 20_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .module_merging(true); } Ok(Vc::upcast(builder.build())) diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index 2289a62628ab6..d16acad63aaf4 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -1030,7 +1030,8 @@ pub async fn get_server_chunking_context_with_client_assets( SourceMapsType::None }) .module_id_strategy(module_id_strategy) - .file_tracing(next_mode.is_production()); + .file_tracing(next_mode.is_production()) + .module_merging(next_mode.is_production()); if next_mode.is_development() { builder = builder.use_file_source_map_uris(); @@ -1095,7 +1096,8 @@ pub async fn get_server_chunking_context( SourceMapsType::None }) .module_id_strategy(module_id_strategy) - .file_tracing(next_mode.is_production()); + .file_tracing(next_mode.is_production()) + .module_merging(next_mode.is_production()); if next_mode.is_development() { builder = builder.use_file_source_map_uris() diff --git a/turbopack/crates/turbopack-browser/src/chunking_context.rs b/turbopack/crates/turbopack-browser/src/chunking_context.rs index 84f451e4dd677..a734fe9f3c78a 100644 --- a/turbopack/crates/turbopack-browser/src/chunking_context.rs +++ b/turbopack/crates/turbopack-browser/src/chunking_context.rs @@ -97,6 +97,11 @@ impl BrowserChunkingContextBuilder { self } + pub fn module_merging(mut self, enable_module_merging: bool) -> Self { + self.chunking_context.enable_module_merging = enable_module_merging; + self + } + pub fn asset_base_path(mut self, asset_base_path: ResolvedVc>) -> Self { self.chunking_context.asset_base_path = asset_base_path; self @@ -202,6 +207,8 @@ pub struct BrowserChunkingContext { enable_hot_module_replacement: bool, /// Enable tracing for this chunking enable_tracing: bool, + /// Enable module merging + enable_module_merging: bool, /// The environment chunks will be evaluated in. environment: ResolvedVc, /// The kind of runtime to include in the output. @@ -248,6 +255,7 @@ impl BrowserChunkingContext { asset_base_path: ResolvedVc::cell(None), enable_hot_module_replacement: false, enable_tracing: false, + enable_module_merging: false, environment, runtime_type, minify_type: MinifyType::NoMinify, @@ -514,6 +522,11 @@ impl ChunkingContext for BrowserChunkingContext { Vc::cell(self.enable_tracing) } + #[turbo_tasks::function] + fn is_module_merging_enabled(&self) -> Vc { + Vc::cell(self.enable_module_merging) + } + #[turbo_tasks::function] pub fn minify_type(&self) -> Vc { self.minify_type.cell() diff --git a/turbopack/crates/turbopack-cli/src/build/mod.rs b/turbopack/crates/turbopack-cli/src/build/mod.rs index 005d00f979c13..d8d4a6ec09255 100644 --- a/turbopack/crates/turbopack-cli/src/build/mod.rs +++ b/turbopack/crates/turbopack-cli/src/build/mod.rs @@ -343,23 +343,25 @@ async fn build_internal( match *node_env.await? { NodeEnv::Development => {} NodeEnv::Production => { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 50_000, - max_chunk_count_per_group: 40, - max_merge_chunk_size: 200_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); - builder = builder.use_content_hashing(ContentHashing::Direct { length: 16 }) + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 50_000, + max_chunk_count_per_group: 40, + max_merge_chunk_size: 200_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .use_content_hashing(ContentHashing::Direct { length: 16 }) + .module_merging(true); } } @@ -387,22 +389,24 @@ async fn build_internal( match *node_env.await? { NodeEnv::Development => {} NodeEnv::Production => { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 20_000, - max_chunk_count_per_group: 100, - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 20_000, + max_chunk_count_per_group: 100, + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .module_merging(true); } } diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs index e6b37c8de5af5..6544240542414 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs @@ -2,6 +2,7 @@ use std::{collections::HashSet, sync::atomic::AtomicBool}; use anyhow::{Context, Result}; use rustc_hash::FxHashMap; +use smallvec::{SmallVec, smallvec}; use turbo_tasks::{FxIndexSet, ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, Value, Vc}; use super::{ @@ -45,6 +46,7 @@ pub async fn make_chunk_group( ChunkLoading::Edge ); let should_trace = *chunking_context.is_tracing_enabled().await?; + let should_merge_modules = *chunking_context.is_module_merging_enabled().await?; let batching_config = chunking_context.batching_config(); let ChunkGroupContent { @@ -58,6 +60,7 @@ pub async fn make_chunk_group( availability_info, can_split_async, should_trace, + should_merge_modules, batching_config, ) .await?; @@ -189,10 +192,10 @@ pub async fn chunk_group_content( availability_info: AvailabilityInfo, can_split_async: bool, should_trace: bool, + should_merge_modules: bool, batching_config: Vc, ) -> Result { let module_batches_graph = module_graph.module_batches(batching_config).await?; - let merged_modules = module_graph.merged_modules().await?; type ModuleToChunkableMap = FxHashMap; @@ -316,62 +319,66 @@ pub async fn chunk_group_content( }, )?; - state.chunkable_items = state - .chunkable_items - .into_iter() - .map(async |chunkable_module| match chunkable_module { - ChunkableModuleOrBatch::Module(module) => { - if !merged_modules.should_create_chunk_item_for(ResolvedVc::upcast(module)) { - return Ok(vec![]); - } + if should_merge_modules { + let merged_modules = module_graph.merged_modules().await?; + state.chunkable_items = state + .chunkable_items + .into_iter() + .map(async |chunkable_module| match chunkable_module { + ChunkableModuleOrBatch::Module(module) => { + if !merged_modules.should_create_chunk_item_for(ResolvedVc::upcast(module)) { + return Ok(smallvec![]); + } - Ok(vec![ChunkableModuleOrBatch::Module( - merged_modules - .should_replace_module(ResolvedVc::upcast(module)) - .unwrap_or(module), - )]) - } - ChunkableModuleOrBatch::Batch(batch) => { - let batch_ref = batch.await?; - let modules = &batch_ref.modules; - - let modified = AtomicBool::new(false); - let modules = modules - .iter() - .filter(|module| { - if merged_modules.should_create_chunk_item_for(ResolvedVc::upcast(**module)) - { - true - } else { - modified.store(true, std::sync::atomic::Ordering::Release); - false - } - }) - .map(|&module| { - if let Some(module) = - merged_modules.should_replace_module(ResolvedVc::upcast(module)) - { - modified.store(true, std::sync::atomic::Ordering::Release); - module - } else { - module - } - }) - .map(ChunkableModuleOrBatch::Module) - .collect::>(); - - if modified.load(std::sync::atomic::Ordering::Acquire) { - Ok(modules) - } else { - Ok(vec![ChunkableModuleOrBatch::Batch(batch)]) + Ok(vec![ChunkableModuleOrBatch::Module( + merged_modules + .should_replace_module(ResolvedVc::upcast(module)) + .unwrap_or(module), + )]) } - } - ChunkableModuleOrBatch::None(i) => Ok(vec![ChunkableModuleOrBatch::None(i)]), - }) - .try_flat_join() - .await? - .into_iter() - .collect(); + ChunkableModuleOrBatch::Batch(batch) => { + let batch_ref = batch.await?; + let modules = &batch_ref.modules; + + let modified = AtomicBool::new(false); + let modules = modules + .iter() + .filter(|module| { + if merged_modules + .should_create_chunk_item_for(ResolvedVc::upcast(**module)) + { + true + } else { + modified.store(true, std::sync::atomic::Ordering::Release); + false + } + }) + .map(|&module| { + if let Some(module) = + merged_modules.should_replace_module(ResolvedVc::upcast(module)) + { + modified.store(true, std::sync::atomic::Ordering::Release); + module + } else { + module + } + }) + .map(ChunkableModuleOrBatch::Module) + .collect::>(); + + if modified.load(std::sync::atomic::Ordering::Acquire) { + Ok(modules) + } else { + Ok(smallvec![ChunkableModuleOrBatch::Batch(batch)]) + } + } + ChunkableModuleOrBatch::None(i) => Ok(smallvec![ChunkableModuleOrBatch::None(i)]), + }) + .try_flat_join() + .await? + .into_iter() + .collect(); + } let mut batch_groups = FxIndexSet::default(); for &module in &state.chunkable_items { diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs index 9b7871da6d3fe..212ee5112fd8e 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs @@ -193,10 +193,17 @@ pub trait ChunkingContext { }) } + /// Whether `ChunkingType::Traced` are used to create corresponding output assets for each + /// traced module. fn is_tracing_enabled(self: Vc) -> Vc { Vc::cell(false) } + /// Whether to use `MergableModule` to merge modules if possible. + fn is_module_merging_enabled(self: Vc) -> Vc { + Vc::cell(false) + } + fn minify_type(self: Vc) -> Vc { MinifyType::NoMinify.cell() } diff --git a/turbopack/crates/turbopack-nodejs/src/chunking_context.rs b/turbopack/crates/turbopack-nodejs/src/chunking_context.rs index 2b65b9945392e..ce2ccbf0292b9 100644 --- a/turbopack/crates/turbopack-nodejs/src/chunking_context.rs +++ b/turbopack/crates/turbopack-nodejs/src/chunking_context.rs @@ -56,6 +56,11 @@ impl NodeJsChunkingContextBuilder { self } + pub fn module_merging(mut self, enable_module_merging: bool) -> Self { + self.chunking_context.enable_module_merging = enable_module_merging; + self + } + pub fn runtime_type(mut self, runtime_type: RuntimeType) -> Self { self.chunking_context.runtime_type = runtime_type; self @@ -119,6 +124,8 @@ pub struct NodeJsChunkingContext { runtime_type: RuntimeType, /// Enable tracing for this chunking enable_file_tracing: bool, + /// Enable module merging + enable_module_merging: bool, /// Whether to minify resulting chunks minify_type: MinifyType, /// Whether to generate source maps @@ -155,6 +162,7 @@ impl NodeJsChunkingContext { asset_root_path, asset_prefix: ResolvedVc::cell(None), enable_file_tracing: false, + enable_module_merging: false, environment, runtime_type, minify_type: MinifyType::NoMinify, @@ -248,6 +256,11 @@ impl ChunkingContext for NodeJsChunkingContext { Vc::cell(self.enable_file_tracing) } + #[turbo_tasks::function] + fn is_module_merging_enabled(&self) -> Vc { + Vc::cell(self.enable_module_merging) + } + #[turbo_tasks::function] pub fn minify_type(&self) -> Vc { self.minify_type.cell() diff --git a/turbopack/crates/turbopack-tests/tests/execution.rs b/turbopack/crates/turbopack-tests/tests/execution.rs index 7c74ca56815f1..85e5ba1d1dca1 100644 --- a/turbopack/crates/turbopack-tests/tests/execution.rs +++ b/turbopack/crates/turbopack-tests/tests/execution.rs @@ -435,6 +435,7 @@ async fn run_test_operation(prepared_test: ResolvedVc) -> Result Date: Fri, 23 May 2025 11:17:35 +0200 Subject: [PATCH 43/59] Turbopack: remove dead code in runtime --- .../js/src/nodejs/runtime.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts index 77a1d6d84eb6d..5906ddf04d2ae 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -251,20 +251,6 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module { ) } - let parents: ModuleId[] - switch (source.type) { - case SourceType.Runtime: - parents = [] - break - case SourceType.Parent: - // No need to add this module as a child of the parent module here, this - // has already been taken care of in `getOrInstantiateModuleFromParent`. - parents = [source.parentId] - break - default: - invariant(source, (source) => `Unknown source type: ${source?.type}`) - } - const module: Module = { exports: {}, error: undefined, From d75f7614ac8cae1f1bfd3ae0c0b72f9fb822688e Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 23 May 2025 14:38:09 +0200 Subject: [PATCH 44/59] Fix module exposing due to splitting --- .../src/module_graph/merged_modules.rs | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index 9dea309551dd5..c839955e05f82 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -272,14 +272,16 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result, > = FxIndexMap::default(); - // A map of all references inside of merged groups, if both modules have the same bitmap - // (and thus are in the same group, unless they are further split up below). - // These are only the references relevant for execution (ignoring cycles) + // A map of all references betwee modules with the same bitmap. These are all references, + // including reexecution edges and cycles. Used to expose additional modules if the + // bitmap-groups are split up further. #[allow(clippy::type_complexity)] let mut intra_group_references: FxIndexMap< ResolvedVc>, FxIndexSet>>, > = FxIndexMap::default(); + // A map of all references betwee modules with the same bitmap. These are only the + // references relevant for execution (ignoring cycles), to find the entries of a group. #[allow(clippy::type_complexity)] let mut intra_group_references_rev: FxIndexMap< ResolvedVc>, @@ -356,10 +358,6 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result>> = FxHashSet::with_capacity_and_hasher(module_merged_groups.len(), Default::default()); - // These have to be exposed, but we might need to expose more modules if the lists are split - // up further below. + module_graph .traverse_edges_from_entries_topological( entries, @@ -405,6 +404,18 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result) -> Result) -> Result) -> Result Date: Fri, 23 May 2025 15:21:01 +0200 Subject: [PATCH 45/59] Proper stubs for snapshots --- .../tests/snapshot/node_modules/@emotion/react/index.js | 5 +++-- .../node_modules/@emotion/react/jsx-dev-runtime.js | 5 +++-- .../snapshot/node_modules/@emotion/react/jsx-runtime.js | 8 ++++++-- .../node_modules/@swc/helpers/_/_class_call_check.js | 5 +++-- .../tests/snapshot/node_modules/react/index.js | 5 +++-- .../tests/snapshot/node_modules/react/jsx-dev-runtime.js | 5 +++-- .../tests/snapshot/node_modules/react/jsx-runtime.js | 8 ++++++-- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js index 9d2737fd0b1b5..6904604683173 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js @@ -1,2 +1,3 @@ -"purposefully empty stub"; -"@emtion/react/index.js"; +export function jsx() { + return 'purposefully empty stub for @emotion/react/index.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js index eee7c33dd5e39..d5d921ad46b8b 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js @@ -1,2 +1,3 @@ -"purposefully empty stub"; -"@emtion/react/jsx-dev-runtime.js"; +export function jsxDEV() { + return 'purposefully empty stub for @emotion/react/jsx-dev-runtime.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js index 885532e7a31df..e849b32f98a35 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js @@ -1,2 +1,6 @@ -"purposefully empty stub"; -"@emtion/react/jsx-runtime.js"; +export function jsx() { + return 'purposefully empty stub for @emotion/react/jsx-runtime.js' +} +export function jsxs() { + return 'purposefully empty stub for @emotion/react/jsx-runtime.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js index e66813ad2bca4..457130ced6414 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js @@ -1,2 +1,3 @@ -"purposefully empty stub"; -"@swc/helpers/_/_class_call_check.js"; +export function _() { + return 'purposefully empty stub for @swc/helpers/_/_class_call_check.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js index f115b2d8e1395..98e53699f5402 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js @@ -1,2 +1,3 @@ -"purposefully empty stub"; -"react/index.js"; +export function jsx() { + return 'purposefully empty stub for react/index.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js index f561dbe24f620..99633e29cba2f 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js @@ -1,2 +1,3 @@ -"purposefully empty stub"; -"react/jsx-dev-runtime.js"; +export function jsxDEV() { + return 'purposefully empty stub for react/jsx-dev-runtime.js' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js index ee1da08297184..35cdcbf319d0f 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js @@ -1,2 +1,6 @@ -"purposefully empty stub"; -"react/jsx-runtime.js"; +export function jsx() { + return 'purposefully empty stub for react/jsx-runtime.js' +} +export function jsxs() { + return 'purposefully empty stub for react/jsx-runtime.js' +} From 7af032ce25550dabfac81f47f5e72ebf4ed463a8 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 27 May 2025 09:12:48 +0200 Subject: [PATCH 46/59] Add turbopackScopeHoisting setting --- crates/next-api/src/project.rs | 5 ++ crates/next-core/src/next_client/context.rs | 3 +- crates/next-core/src/next_config.rs | 9 +++ crates/next-core/src/next_edge/context.rs | 6 +- crates/next-core/src/next_server/context.rs | 76 +++++++++++---------- packages/next/src/server/config-schema.ts | 1 + packages/next/src/server/config-shared.ts | 5 ++ 7 files changed, 66 insertions(+), 39 deletions(-) diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index a5ff9d9371cc6..f1eccd9e7d61f 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -1007,6 +1007,7 @@ impl Project { self.next_config().turbo_minify(self.next_mode()), self.next_config().client_source_maps(self.next_mode()), self.no_mangling(), + self.next_config().turbo_scope_hoisting(self.next_mode()), ) } @@ -1028,6 +1029,7 @@ impl Project { self.next_config().turbo_minify(self.next_mode()), self.next_config().server_source_maps(), self.no_mangling(), + self.next_config().turbo_scope_hoisting(self.next_mode()), ) } else { get_server_chunking_context( @@ -1040,6 +1042,7 @@ impl Project { self.next_config().turbo_minify(self.next_mode()), self.next_config().server_source_maps(), self.no_mangling(), + self.next_config().turbo_scope_hoisting(self.next_mode()), ) } } @@ -1062,6 +1065,7 @@ impl Project { self.next_config().turbo_minify(self.next_mode()), self.next_config().server_source_maps(), self.no_mangling(), + self.next_config().turbo_scope_hoisting(self.next_mode()), ) } else { get_edge_chunking_context( @@ -1074,6 +1078,7 @@ impl Project { self.next_config().turbo_minify(self.next_mode()), self.next_config().server_source_maps(), self.no_mangling(), + self.next_config().turbo_scope_hoisting(self.next_mode()), ) } } diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index b0a61f72d5018..ef22e9e178511 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -437,6 +437,7 @@ pub async fn get_client_chunking_context( minify: Vc, source_maps: Vc, no_mangling: Vc, + scope_hoisting: Vc, ) -> Result>> { let next_mode = mode.await?; let mut builder = BrowserChunkingContext::builder( @@ -491,7 +492,7 @@ pub async fn get_client_chunking_context( }, ) .use_content_hashing(ContentHashing::Direct { length: 16 }) - .module_merging(true); + .module_merging(*scope_hoisting.await?); } Ok(Vc::upcast(builder.build())) diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index 51666aafad382..d9a6699461cd9 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -795,6 +795,7 @@ pub struct ExperimentalConfig { turbopack_persistent_caching: Option, turbopack_source_maps: Option, turbopack_tree_shaking: Option, + turbopack_scope_hoisting: Option, // Whether to enable the global-not-found convention global_not_found: Option, /// Defaults to false in development mode, true in production mode. @@ -1585,6 +1586,14 @@ impl NextConfig { )) } + #[turbo_tasks::function] + pub async fn turbo_scope_hoisting(&self, mode: Vc) -> Result> { + let minify = self.experimental.turbopack_scope_hoisting; + Ok(Vc::cell( + minify.unwrap_or(matches!(*mode.await?, NextMode::Build)), + )) + } + #[turbo_tasks::function] pub async fn client_source_maps(&self, _mode: Vc) -> Result> { // Temporarily always enable client source maps as tests regress. diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index 12df8bee1802d..95569dcf4a9f6 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -222,6 +222,7 @@ pub async fn get_edge_chunking_context_with_client_assets( turbo_minify: Vc, turbo_source_maps: Vc, no_mangling: Vc, + scope_hoisting: Vc, ) -> Result>> { let output_root = node_root.join("server/edge".into()).to_resolved().await?; let next_mode = mode.await?; @@ -270,7 +271,7 @@ pub async fn get_edge_chunking_context_with_client_assets( ..Default::default() }, ) - .module_merging(true); + .module_merging(*scope_hoisting.await?); } Ok(Vc::upcast(builder.build())) @@ -287,6 +288,7 @@ pub async fn get_edge_chunking_context( turbo_minify: Vc, turbo_source_maps: Vc, no_mangling: Vc, + scope_hoisting: Vc, ) -> Result>> { let output_root = node_root.join("server/edge".into()).to_resolved().await?; let next_mode = mode.await?; @@ -335,7 +337,7 @@ pub async fn get_edge_chunking_context( ..Default::default() }, ) - .module_merging(true); + .module_merging(*scope_hoisting.await?); } Ok(Vc::upcast(builder.build())) diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index d16acad63aaf4..db69aee3b0abd 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -994,6 +994,7 @@ pub async fn get_server_chunking_context_with_client_assets( turbo_minify: Vc, turbo_source_maps: Vc, no_mangling: Vc, + scope_hoisting: Vc, ) -> Result> { let next_mode = mode.await?; // TODO(alexkirsz) This should return a trait that can be implemented by the @@ -1030,28 +1031,29 @@ pub async fn get_server_chunking_context_with_client_assets( SourceMapsType::None }) .module_id_strategy(module_id_strategy) - .file_tracing(next_mode.is_production()) - .module_merging(next_mode.is_production()); + .file_tracing(next_mode.is_production()); if next_mode.is_development() { builder = builder.use_file_source_map_uris(); } else { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 20_000, - max_chunk_count_per_group: 100, - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 20_000, + max_chunk_count_per_group: 100, + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .module_merging(*scope_hoisting.await?); } Ok(builder.build()) @@ -1068,6 +1070,7 @@ pub async fn get_server_chunking_context( turbo_minify: Vc, turbo_source_maps: Vc, no_mangling: Vc, + scope_hoisting: Vc, ) -> Result> { let next_mode = mode.await?; // TODO(alexkirsz) This should return a trait that can be implemented by the @@ -1096,28 +1099,29 @@ pub async fn get_server_chunking_context( SourceMapsType::None }) .module_id_strategy(module_id_strategy) - .file_tracing(next_mode.is_production()) - .module_merging(next_mode.is_production()); + .file_tracing(next_mode.is_production()); if next_mode.is_development() { builder = builder.use_file_source_map_uris() } else { - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - min_chunk_size: 20_000, - max_chunk_count_per_group: 100, - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); - builder = builder.chunking_config( - Vc::::default().to_resolved().await?, - ChunkingConfig { - max_merge_chunk_size: 100_000, - ..Default::default() - }, - ); + builder = builder + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + min_chunk_size: 20_000, + max_chunk_count_per_group: 100, + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .chunking_config( + Vc::::default().to_resolved().await?, + ChunkingConfig { + max_merge_chunk_size: 100_000, + ..Default::default() + }, + ) + .module_merging(*scope_hoisting.await?); } Ok(builder.build()) diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index a76addf23c834..b4d1b8f2d78e6 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -461,6 +461,7 @@ export const configSchema: zod.ZodType = z.lazy(() => turbopackSourceMaps: z.boolean().optional(), turbopackTreeShaking: z.boolean().optional(), turbopackRemoveUnusedExports: z.boolean().optional(), + turbopackScopeHoisting: z.boolean().optional(), optimizePackageImports: z.array(z.string()).optional(), optimizeServerReact: z.boolean().optional(), clientTraceMetadata: z.array(z.string()).optional(), diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 242bda88362d2..366328eab605b 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -417,6 +417,11 @@ export interface ExperimentalConfig { */ turbopackMinify?: boolean + /** + * Enable scope hoisting. Defaults to true in build mode and false in dev mode. + */ + turbopackScopeHoisting?: boolean + /** * Enable persistent caching for the turbopack dev server and build. */ From f91f7ea9489debcc942d99f9d3b06adf9de614d5 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 27 May 2025 16:21:33 +0200 Subject: [PATCH 47/59] Cleanup --- .../turbopack-core/src/chunk/chunk_group.rs | 53 ++++++++++++++++--- .../src/module_graph/merged_modules.rs | 19 +++++-- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs index 6544240542414..be29d0f2c3c4e 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs @@ -321,6 +321,23 @@ pub async fn chunk_group_content( if should_merge_modules { let merged_modules = module_graph.merged_modules().await?; + // let old_items: Vec>> = state + // .chunkable_items + // .iter() + // .map(async |m| { + // Ok(match m { + // ChunkableModuleOrBatch::Module(module) => vec![ResolvedVc::upcast(*module)], + // ChunkableModuleOrBatch::Batch(batch) => batch + // .await? + // .modules + // .iter() + // .map(|m| ResolvedVc::upcast(*m)) + // .collect(), + // ChunkableModuleOrBatch::None(_) => vec![], + // }) + // }) + // .try_flat_join() + // .await?; state.chunkable_items = state .chunkable_items .into_iter() @@ -330,11 +347,24 @@ pub async fn chunk_group_content( return Ok(smallvec![]); } - Ok(vec![ChunkableModuleOrBatch::Module( - merged_modules - .should_replace_module(ResolvedVc::upcast(module)) - .unwrap_or(module), - )]) + let module = if let Some(replacement) = + merged_modules.should_replace_module(ResolvedVc::upcast(module)) + { + // debug_assert!( + // merged_modules + // .replacements_included + // .get(&ResolvedVc::upcast(module)) + // .unwrap() + // .iter() + // .all(|m| old_items.contains(m)), + // "Hoisting included too many modules", + // ); + replacement + } else { + module + }; + + Ok(smallvec![ChunkableModuleOrBatch::Module(module)]) } ChunkableModuleOrBatch::Batch(batch) => { let batch_ref = batch.await?; @@ -354,11 +384,20 @@ pub async fn chunk_group_content( } }) .map(|&module| { - if let Some(module) = + if let Some(replacement) = merged_modules.should_replace_module(ResolvedVc::upcast(module)) { + // debug_assert!( + // merged_modules + // .replacements_included + // .get(&ResolvedVc::upcast(module)) + // .unwrap() + // .iter() + // .all(|m| old_items.contains(m)), + // "Hoisting included too many modules", + // ); modified.store(true, std::sync::atomic::Ordering::Release); - module + replacement } else { module } diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index c839955e05f82..befc311ea5bde 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -37,6 +37,9 @@ pub struct MergedModuleInfo { /// A map of modules to the merged module containing the module plus additional modules. #[allow(clippy::type_complexity)] pub replacements: FxHashMap>, ResolvedVc>>, + // #[allow(clippy::type_complexity)] + // pub replacements_included: + // FxHashMap>, Vec>>>, /// A map of modules that are already contained as values in replacements. pub included: FxHashSet>>, } @@ -729,7 +732,8 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>(entry), result)], + ResolvedVc::upcast::>(entry), + result, list.into_iter() .take(list_len - 1) .map(ResolvedVc::upcast) @@ -813,11 +817,17 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result>, ResolvedVc>, > = Default::default(); + // #[allow(clippy::type_complexity)] + // let mut replacements_included: FxHashMap< + // ResolvedVc>, + // Vec>>, + // > = Default::default(); let mut included: FxHashSet>> = FxHashSet::default(); - for (replacements_part, included_part) in result.into_iter().flatten() { - replacements.extend(replacements_part.into_iter()); - included.extend(included_part); + for (original, replacement, replacement_included) in result.into_iter().flatten() { + replacements.insert(original, replacement); + // replacements_included.insert(original, replacement_included.clone()); + included.extend(replacement_included); } span.record("merged_groups", replacements.len()); @@ -845,6 +855,7 @@ pub async fn compute_merged_modules(module_graph: Vc) -> Result Date: Wed, 28 May 2025 16:30:45 +0200 Subject: [PATCH 48/59] Cleanup --- .../src/module_graph/merged_modules.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs index befc311ea5bde..598e5aa563d7a 100644 --- a/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs +++ b/turbopack/crates/turbopack-core/src/module_graph/merged_modules.rs @@ -5,8 +5,7 @@ use roaring::RoaringBitmap; use rustc_hash::{FxHashMap, FxHashSet}; use tracing::Instrument; use turbo_tasks::{ - FxIndexMap, FxIndexSet, ResolvedVc, SliceMap, TryFlatJoinIterExt, TryJoinIterExt, - ValueToString, Vc, + FxIndexMap, FxIndexSet, ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, ValueToString, Vc, }; use crate::{ @@ -21,17 +20,6 @@ use crate::{ resolve::ExportUsage, }; -#[turbo_tasks::value(transparent)] -pub struct MergedModules(SliceMap>, bool>); -#[turbo_tasks::value_impl] -impl MergedModules { - #[turbo_tasks::function] - pub fn empty() -> Vc { - Vc::cell(Default::default()) - } -} - -// TODO maybe a smallvec once we know the size distribution? #[turbo_tasks::value] pub struct MergedModuleInfo { /// A map of modules to the merged module containing the module plus additional modules. From f611dabe9c675bfebf405f25819df766cac06abd Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 23 May 2025 15:22:23 +0200 Subject: [PATCH 49/59] Update snapshots --- ...shake_dynamic-import_input_lib_b2d8c81e.js | 52 ++++++------ ...ree-shake_export-named_input_058a40bc._.js | 16 ++-- ...shake_export-namespace_input_f7fde6f3._.js | 48 +++++------ ...shake_import-named-all_input_00b867a0._.js | 10 +-- ...ree-shake_import-named_input_f64e7412._.js | 10 +-- ...shake_import-namespace_input_25e69485._.js | 44 +++++----- ...ake_import-side-effect_input_e082b9f6._.js | 4 +- ...ke_require-side-effect_input_f83a22d6._.js | 52 ++++++------ ..._tree-shake-test-1_input_index_09a16221.js | 52 ++++++------ ...shot_basic_async_chunk_input_46366300._.js | 2 +- ...shot_basic_async_chunk_input_b274c771._.js | 2 +- ...asic_async_chunk_build_input_1e41378a._.js | 2 +- ...asic_async_chunk_build_input_23e8ba79._.js | 2 +- ...snapshot_basic_chunked_input_1efdaca0._.js | 2 +- ...snapshot_basic_shebang_input_d5e8dcd4._.js | 2 +- ..._basic_top-level-await_input_9acd43f4._.js | 4 +- ..._basic_top-level-await_input_aa0a0c39._.js | 8 +- ..._comptime_early-return_input_82bbae08._.js | 20 ++--- ...rbopack-tests_tests_snapshot_6fdc60d8._.js | 30 ++++--- ...ack-tests_tests_snapshot_6fdc60d8._.js.map | 6 +- ...orts_duplicate-binding_input_8498b7ee._.js | 4 +- ...rts_dynamic_input_vercel_mjs_7f2965b8._.js | 2 +- ...re-comments_input_vercel_mjs_9a2c4881._.js | 2 +- ...mports_ignore-comments_input_7f940ff3._.js | 2 +- ...snapshot_imports_order_input_152f317f._.js | 2 +- ...nd____c__ Can't resolve __c_'d-1bcd44.txt} | 2 +- ...rts_static-and-dynamic_input_ab9cac73._.js | 2 +- ...subpath-imports-nested_input_2e0531bf._.js | 4 +- ...mports_subpath-imports_input_1e655205._.js | 8 +- ...hake_tree-shake-test-1_input_80df1e23._.js | 2 +- ...hot_node_spawn_dynamic_input_d33fdf1c._.js | 2 +- ...t_node_spawn_node_eval_input_bf21d136._.js | 2 +- .../output/[turbopack]_runtime.js | 81 +++++++++++++------ .../output/[turbopack]_runtime.js.map | 10 +-- ...efault_dev_runtime_input_index_75df6705.js | 56 ++++++++++--- ...lt_dev_runtime_input_index_75df6705.js.map | 10 +-- ...rbopack-tests_tests_snapshot_b56e07c9._.js | 19 +++-- ...ack-tests_tests_snapshot_b56e07c9._.js.map | 4 +- ...rbopack-tests_tests_snapshot_bff03a32._.js | 15 ++-- ...ack-tests_tests_snapshot_bff03a32._.js.map | 2 +- ...cript_jsconfig-baseurl_input_50efc170._.js | 2 +- ...cript_tsconfig-baseurl_input_88264193._.js | 4 +- ...rbopack-tests_tests_snapshot_f038421b._.js | 2 +- ...rbopack-tests_tests_snapshot_cff3cff1._.js | 2 +- ...g-extends-relative-dir_input_ef6815c7._.js | 2 +- ...ig-extends-without-ext_input_fcdb4390._.js | 2 +- ...cript_tsconfig-extends_input_39e68707._.js | 2 +- 47 files changed, 348 insertions(+), 267 deletions(-) rename turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/{__l___Module not found____c__ Can't resolve __c_'d-4fcf36.txt => __l___Module not found____c__ Can't resolve __c_'d-1bcd44.txt} (93%) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/4c35f_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_b2d8c81e.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/4c35f_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_b2d8c81e.js index 7fe495504f886..1b9c10c1a5d78 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/4c35f_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_b2d8c81e.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/4c35f_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_b2d8c81e.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,19 +50,19 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "b": ([ + "b": [ ()=>getDog, (new_getDog)=>getDog = new_getDog - ]), - "c": ([ + ], + "c": [ ()=>setDog, (new_setDog)=>setDog = new_setDog - ]), - "d": ([ + ], + "d": [ ()=>dogRef, (new_dogRef)=>dogRef = new_dogRef - ]), - "dogRef": (()=>dogRef) + ], + "dogRef": ()=>dogRef }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); @@ -88,10 +88,10 @@ const dogRef = { "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -100,11 +100,11 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "f": ([ + "f": [ ()=>initialCat, (new_initialCat)=>initialCat = new_initialCat - ]), - "initialCat": (()=>initialCat) + ], + "initialCat": ()=>initialCat }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); ; @@ -116,11 +116,11 @@ const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$ "use strict"; __turbopack_context__.s({ - "g": ([ + "g": [ ()=>getChimera, (new_getChimera)=>getChimera = new_getChimera - ]), - "getChimera": (()=>getChimera) + ], + "getChimera": ()=>getChimera }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); @@ -138,7 +138,7 @@ function getChimera() { "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); ; @@ -148,10 +148,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); @@ -166,10 +166,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.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_058a40bc._.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_058a40bc._.js index de018c898cc13..88e0fca1a4b2d 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_058a40bc._.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_058a40bc._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,10 +50,10 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -62,7 +62,7 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); ; @@ -72,11 +72,11 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], (new_cat)=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"] = new_cat - ]), - "fakeCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]) + ], + "fakeCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_f7fde6f3._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_f7fde6f3._.js index 6a6b66abef2b7..f4507d5380e7c 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_f7fde6f3._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_f7fde6f3._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,19 +50,19 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "b": ([ + "b": [ ()=>getDog, (new_getDog)=>getDog = new_getDog - ]), - "c": ([ + ], + "c": [ ()=>setDog, (new_setDog)=>setDog = new_setDog - ]), - "d": ([ + ], + "d": [ ()=>dogRef, (new_dogRef)=>dogRef = new_dogRef - ]), - "dogRef": (()=>dogRef) + ], + "dogRef": ()=>dogRef }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); @@ -88,10 +88,10 @@ const dogRef = { "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -100,11 +100,11 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "f": ([ + "f": [ ()=>initialCat, (new_initialCat)=>initialCat = new_initialCat - ]), - "initialCat": (()=>initialCat) + ], + "initialCat": ()=>initialCat }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); ; @@ -116,11 +116,11 @@ const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$ "use strict"; __turbopack_context__.s({ - "g": ([ + "g": [ ()=>getChimera, (new_getChimera)=>getChimera = new_getChimera - ]), - "getChimera": (()=>getChimera) + ], + "getChimera": ()=>getChimera }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); @@ -138,7 +138,7 @@ function getChimera() { "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); ; @@ -148,10 +148,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); @@ -166,8 +166,8 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "a": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__), - "lib": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__) + "a": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__, + "lib": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_00b867a0._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_00b867a0._.js index a7389e4a5bba7..1b33eac0ccd00 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_00b867a0._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_00b867a0._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,10 +50,10 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -62,7 +62,7 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.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_f64e7412._.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_f64e7412._.js index f638cff873b20..eda2b04c92b9a 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_f64e7412._.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_f64e7412._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,10 +50,10 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -62,7 +62,7 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); ; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_25e69485._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_25e69485._.js index d40f0a045f762..d6b63d7fd90f2 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_25e69485._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/b1abf_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_25e69485._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,19 +50,19 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "b": ([ + "b": [ ()=>getDog, (new_getDog)=>getDog = new_getDog - ]), - "c": ([ + ], + "c": [ ()=>setDog, (new_setDog)=>setDog = new_setDog - ]), - "d": ([ + ], + "d": [ ()=>dogRef, (new_dogRef)=>dogRef = new_dogRef - ]), - "dogRef": (()=>dogRef) + ], + "dogRef": ()=>dogRef }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); @@ -88,10 +88,10 @@ const dogRef = { "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -100,11 +100,11 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "f": ([ + "f": [ ()=>initialCat, (new_initialCat)=>initialCat = new_initialCat - ]), - "initialCat": (()=>initialCat) + ], + "initialCat": ()=>initialCat }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); ; @@ -116,11 +116,11 @@ const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$ "use strict"; __turbopack_context__.s({ - "g": ([ + "g": [ ()=>getChimera, (new_getChimera)=>getChimera = new_getChimera - ]), - "getChimera": (()=>getChimera) + ], + "getChimera": ()=>getChimera }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); @@ -138,7 +138,7 @@ function getChimera() { "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); ; @@ -148,10 +148,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.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_e082b9f6._.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_e082b9f6._.js index 1939a7e5cff42..f667b7bb9b4c4 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_e082b9f6._.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_e082b9f6._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_require-side-effect_input_f83a22d6._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_require-side-effect_input_f83a22d6._.js index f00daa7048414..57bce7e4ff16d 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_require-side-effect_input_f83a22d6._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/4c35f_tests_snapshot_basic-tree-shake_require-side-effect_input_f83a22d6._.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,19 +50,19 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "b": ([ + "b": [ ()=>getDog, (new_getDog)=>getDog = new_getDog - ]), - "c": ([ + ], + "c": [ ()=>setDog, (new_setDog)=>setDog = new_setDog - ]), - "d": ([ + ], + "d": [ ()=>dogRef, (new_dogRef)=>dogRef = new_dogRef - ]), - "dogRef": (()=>dogRef) + ], + "dogRef": ()=>dogRef }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); @@ -88,10 +88,10 @@ const dogRef = { "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -100,11 +100,11 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "f": ([ + "f": [ ()=>initialCat, (new_initialCat)=>initialCat = new_initialCat - ]), - "initialCat": (()=>initialCat) + ], + "initialCat": ()=>initialCat }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); ; @@ -116,11 +116,11 @@ const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$ "use strict"; __turbopack_context__.s({ - "g": ([ + "g": [ ()=>getChimera, (new_getChimera)=>getChimera = new_getChimera - ]), - "getChimera": (()=>getChimera) + ], + "getChimera": ()=>getChimera }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); @@ -138,7 +138,7 @@ function getChimera() { "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); ; @@ -148,10 +148,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); @@ -166,10 +166,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.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_09a16221.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_09a16221.js index adea424ec6b28..26206336f7389 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_09a16221.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_09a16221.js @@ -4,10 +4,10 @@ "use strict"; __turbopack_context__.s({ - "a": ([ + "a": [ ()=>dog, (new_dog)=>dog = new_dog - ]) + ] }); let dog = 'dog'; ; @@ -50,19 +50,19 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "b": ([ + "b": [ ()=>getDog, (new_getDog)=>getDog = new_getDog - ]), - "c": ([ + ], + "c": [ ()=>setDog, (new_setDog)=>setDog = new_setDog - ]), - "d": ([ + ], + "d": [ ()=>dogRef, (new_dogRef)=>dogRef = new_dogRef - ]), - "dogRef": (()=>dogRef) + ], + "dogRef": ()=>dogRef }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); @@ -88,10 +88,10 @@ const dogRef = { "use strict"; __turbopack_context__.s({ - "e": ([ + "e": [ ()=>cat, (new_cat)=>cat = new_cat - ]) + ] }); let cat = 'cat'; ; @@ -100,11 +100,11 @@ let cat = 'cat'; "use strict"; __turbopack_context__.s({ - "f": ([ + "f": [ ()=>initialCat, (new_initialCat)=>initialCat = new_initialCat - ]), - "initialCat": (()=>initialCat) + ], + "initialCat": ()=>initialCat }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); ; @@ -116,11 +116,11 @@ const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$ "use strict"; __turbopack_context__.s({ - "g": ([ + "g": [ ()=>getChimera, (new_getChimera)=>getChimera = new_getChimera - ]), - "getChimera": (()=>getChimera) + ], + "getChimera": ()=>getChimera }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); @@ -138,7 +138,7 @@ function getChimera() { "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["e"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); ; @@ -148,10 +148,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__3$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); @@ -166,10 +166,10 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "cat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"]), - "dogRef": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"]), - "getChimera": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"]), - "initialCat": (()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"]) + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_context__.i("[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/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_46366300._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_46366300._.js index 6564e1e3750dd..723ea9a4e9da3 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_46366300._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_46366300._.js @@ -23,7 +23,7 @@ __turbopack_context__.r("[project]/turbopack/crates/turbopack-tests/tests/snapsh "use strict"; __turbopack_context__.s({ - "bar": (()=>bar) + "bar": ()=>bar }); function bar(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_b274c771._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_b274c771._.js index b8c630564703e..e5861e2336950 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_b274c771._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_b274c771._.js @@ -17,7 +17,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "foo": (()=>foo) + "foo": ()=>foo }); function foo(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_1e41378a._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_1e41378a._.js index a4fba27e15aa8..736325e56c73e 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_1e41378a._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_1e41378a._.js @@ -23,7 +23,7 @@ __turbopack_context__.r("[project]/turbopack/crates/turbopack-tests/tests/snapsh "use strict"; __turbopack_context__.s({ - "bar": (()=>bar) + "bar": ()=>bar }); function bar(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_23e8ba79._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_23e8ba79._.js index 0841a1282a498..9ffd17caf23e5 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_23e8ba79._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/4e721_crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_23e8ba79._.js @@ -17,7 +17,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "foo": (()=>foo) + "foo": ()=>foo }); function foo(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_chunked_input_1efdaca0._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_chunked_input_1efdaca0._.js index 7acbb88ea8c88..fc5106b922a40 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_chunked_input_1efdaca0._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_chunked_input_1efdaca0._.js @@ -12,7 +12,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "foo": (()=>foo) + "foo": ()=>foo }); function foo(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_shebang_input_d5e8dcd4._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_shebang_input_d5e8dcd4._.js index 0eccb969e8fd4..85c80d002fba8 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_shebang_input_d5e8dcd4._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/turbopack_crates_turbopack-tests_tests_snapshot_basic_shebang_input_d5e8dcd4._.js @@ -12,7 +12,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo "use strict"; __turbopack_context__.s({ - "foo": (()=>foo) + "foo": ()=>foo }); function foo(value) { console.assert(value); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_9acd43f4._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_9acd43f4._.js index 012a1cf1c2e3b..ba1aeefa4826b 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_9acd43f4._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_9acd43f4._.js @@ -5,8 +5,8 @@ // import() doesn't care about whether a module is an async module or not __turbopack_context__.s({ - "AlternativeCreateUserAction": (()=>AlternativeCreateUserAction), - "CreateUserAction": (()=>CreateUserAction) + "AlternativeCreateUserAction": ()=>AlternativeCreateUserAction, + "CreateUserAction": ()=>CreateUserAction }); const UserApi = __turbopack_context__.r("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript, async loader)")(__turbopack_context__.i); const CreateUserAction = async (name)=>{ diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_aa0a0c39._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_aa0a0c39._.js index 01a178463a801..5a04fcf5c3921 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_aa0a0c39._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/4e721_crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_aa0a0c39._.js @@ -6,8 +6,8 @@ var { a: __turbopack_async_module__ } = __turbopack_context__; __turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { __turbopack_context__.s({ - "close": (()=>close), - "dbCall": (()=>dbCall) + "close": ()=>close, + "dbCall": ()=>dbCall }); const connectToDB = async (url)=>{ console.log('connecting to db', url); @@ -32,13 +32,13 @@ __turbopack_async_result__(); var { a: __turbopack_async_module__ } = __turbopack_context__; __turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { __turbopack_context__.s({ - "createUser": (()=>createUser) + "createUser": ()=>createUser }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js [test] (ecmascript)"); var __turbopack_async_dependencies__ = __turbopack_handle_async_dependencies__([ __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__ ]); -([__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__] = __turbopack_async_dependencies__.then ? (await __turbopack_async_dependencies__)() : __turbopack_async_dependencies__); +[__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__] = __turbopack_async_dependencies__.then ? (await __turbopack_async_dependencies__)() : __turbopack_async_dependencies__; ; const createUser = async (name)=>{ const command = `CREATE USER ${name}`; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/early-return/output/4e721_crates_turbopack-tests_tests_snapshot_comptime_early-return_input_82bbae08._.js b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/early-return/output/4e721_crates_turbopack-tests_tests_snapshot_comptime_early-return_input_82bbae08._.js index aaea54b5c93c3..53865d9ea6647 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/early-return/output/4e721_crates_turbopack-tests_tests_snapshot_comptime_early-return_input_82bbae08._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/early-return/output/4e721_crates_turbopack-tests_tests_snapshot_comptime_early-return_input_82bbae08._.js @@ -4,16 +4,16 @@ "use strict"; __turbopack_context__.s({ - "a": (()=>a), - "b": (()=>b), - "c": (()=>c), - "d": (()=>d), - "e": (()=>e), - "f": (()=>f), - "g": (()=>g), - "h": (()=>h), - "i": (()=>i), - "j": (()=>j) + "a": ()=>a, + "b": ()=>b, + "c": ()=>c, + "d": ()=>d, + "e": ()=>e, + "f": ()=>f, + "g": ()=>g, + "h": ()=>h, + "i": ()=>i, + "j": ()=>j }); function a() { if ("TURBOPACK compile-time truthy", 1) { diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js index 13c748c8ab46d..7bbfb1f4827c4 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js @@ -27,20 +27,26 @@ function ClassNameButton({ children }) { } console.log(StyledButton, ClassNameButton); }), -"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)": (function(__turbopack_context__) { +"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)": ((__turbopack_context__) => { +"use strict"; -var { m: module, e: exports } = __turbopack_context__; -{ -"purposefully empty stub"; -"@emtion/react/jsx-dev-runtime.js"; -}}), -"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)": (function(__turbopack_context__) { +__turbopack_context__.s({ + "jsxDEV": ()=>jsxDEV +}); +function jsxDEV() { + return 'purposefully empty stub for @emotion/react/jsx-dev-runtime.js'; +} +}), +"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)": ((__turbopack_context__) => { +"use strict"; -var { m: module, e: exports } = __turbopack_context__; -{ -"purposefully empty stub"; -"@emtion/react/index.js"; -}}), +__turbopack_context__.s({ + "jsx": ()=>jsx +}); +function jsx() { + return 'purposefully empty stub for @emotion/react/index.js'; +} +}), "[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js [test] (ecmascript)": (function(__turbopack_context__) { var { m: module, e: exports } = __turbopack_context__; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js.map index 97e1d50016a39..73d024ecbb543 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js.map +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/turbopack_crates_turbopack-tests_tests_snapshot_6fdc60d8._.js.map @@ -3,7 +3,7 @@ "sources": [], "sections": [ {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from '@emotion/react'\nimport styled from '@emotion/styled'\n\nconst StyledButton = styled.button`\n background: blue;\n`\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n )\n}\n\nconsole.log(StyledButton, ClassNameButton)\n"],"names":[],"mappings":"AAAA,oCAAoC;;AAEpC;AACA;;;;AAEA,MAAM,6BAAe,CAAA,GAAA,wMAAA,CAAA,UAAM,AAAD;;;AAI1B,SAAS,gBAAgB,EAAE,QAAQ,EAAE;IACnC,qBACE,uOAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, - {"offset": {"line": 33, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}, - {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/index.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}, - {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/styled/index.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}] + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js"],"sourcesContent":["export function jsxDEV() {\n return 'purposefully empty stub for @emotion/react/jsx-dev-runtime.js'\n}\n"],"names":[],"mappings":";;;AAAO,SAAS;IACd,OAAO;AACT","ignoreList":[0]}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js"],"sourcesContent":["export function jsx() {\n return 'purposefully empty stub for @emotion/react/index.js'\n}\n"],"names":[],"mappings":";;;AAAO,SAAS;IACd,OAAO;AACT","ignoreList":[0]}}, + {"offset": {"line": 53, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/styled/index.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}] } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/4e721_crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_8498b7ee._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/4e721_crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_8498b7ee._.js index 3ca8c66254692..d0faf61d1a155 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/4e721_crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_8498b7ee._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/4e721_crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_8498b7ee._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "Table": (()=>Table) + "Table": ()=>Table }); const Table = ()=>{ return 'table'; @@ -14,7 +14,7 @@ const Table = ()=>{ "use strict"; __turbopack_context__.s({ - "Table": (()=>Table) + "Table": ()=>Table }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$duplicate$2d$binding$2f$input$2f$table$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js [test] (ecmascript)"); ; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_7f2965b8._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_7f2965b8._.js index 6e432055dd511..dd7593d76c544 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_7f2965b8._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_7f2965b8._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'turbopack'; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4c35f_tests_snapshot_imports_ignore-comments_input_vercel_mjs_9a2c4881._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4c35f_tests_snapshot_imports_ignore-comments_input_vercel_mjs_9a2c4881._.js index ef7387309d0d0..c501bba0ab3a9 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4c35f_tests_snapshot_imports_ignore-comments_input_vercel_mjs_9a2c4881._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4c35f_tests_snapshot_imports_ignore-comments_input_vercel_mjs_9a2c4881._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'turbopack'; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4e721_crates_turbopack-tests_tests_snapshot_imports_ignore-comments_input_7f940ff3._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4e721_crates_turbopack-tests_tests_snapshot_imports_ignore-comments_input_7f940ff3._.js index 2210edecf4288..e69874bff34c5 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4e721_crates_turbopack-tests_tests_snapshot_imports_ignore-comments_input_7f940ff3._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/ignore-comments/output/4e721_crates_turbopack-tests_tests_snapshot_imports_ignore-comments_input_7f940ff3._.js @@ -23,7 +23,7 @@ __turbopack_context__.v("/static/ignore-worker.c7cb9893.cjs");}), "use strict"; __turbopack_context__.s({ - "foo": (()=>foo) + "foo": ()=>foo }); const __TURBOPACK__import$2e$meta__ = { get url () { diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/turbopack_crates_turbopack-tests_tests_snapshot_imports_order_input_152f317f._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/turbopack_crates_turbopack-tests_tests_snapshot_imports_order_input_152f317f._.js index bed6289527f46..49c998093790f 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/turbopack_crates_turbopack-tests_tests_snapshot_imports_order_input_152f317f._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/turbopack_crates_turbopack-tests_tests_snapshot_imports_order_input_152f317f._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = { js: true diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-4fcf36.txt b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-1bcd44.txt similarity index 93% rename from turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-4fcf36.txt rename to turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-1bcd44.txt index 52431f06c4097..dcd399c3bd776 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-4fcf36.txt +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve __c_'d-1bcd44.txt @@ -13,5 +13,5 @@ error - [resolve] [project]/turbopack/crates/turbopack-tests/tests/snapshot/impo | It was not possible to find the requested file. | Parsed request as written in source code: module "does-not-exist" with subpath '/path' | Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js - | Type of request: EcmaScript Modules request + | Type of request: EcmaScript Modules (part) request | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_ab9cac73._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_ab9cac73._.js index abe303a96f8d6..396895f7f5d38 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_ab9cac73._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_ab9cac73._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'turbopack'; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/b1abf_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_2e0531bf._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/b1abf_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_2e0531bf._.js index 1dcc1e926b211..61f564347df5f 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/b1abf_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_2e0531bf._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/b1abf_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_2e0531bf._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'foo'; }), @@ -12,7 +12,7 @@ const __TURBOPACK__default__export__ = 'foo'; "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js [test] (ecmascript)"); ; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/4e721_crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_1e655205._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/4e721_crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_1e655205._.js index 8b6c88dfacc5f..d9a20d0e2e7ce 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/4e721_crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_1e655205._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/4e721_crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_1e655205._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'foo'; }), @@ -12,7 +12,7 @@ const __TURBOPACK__default__export__ = 'foo'; "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'dep'; }), @@ -20,7 +20,7 @@ const __TURBOPACK__default__export__ = 'dep'; "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'pat'; }), @@ -28,7 +28,7 @@ const __TURBOPACK__default__export__ = 'pat'; "use strict"; __turbopack_context__.s({ - "default": (()=>__TURBOPACK__default__export__) + "default": ()=>__TURBOPACK__default__export__ }); const __TURBOPACK__default__export__ = 'import'; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/intermediate-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_intermediate-tree-shake_tree-shake-test-1_input_80df1e23._.js b/turbopack/crates/turbopack-tests/tests/snapshot/intermediate-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_intermediate-tree-shake_tree-shake-test-1_input_80df1e23._.js index 77b8d0cd17e72..bcbd867f855e9 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/intermediate-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_intermediate-tree-shake_tree-shake-test-1_input_80df1e23._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/intermediate-tree-shake/tree-shake-test-1/output/4c35f_tests_snapshot_intermediate-tree-shake_tree-shake-test-1_input_80df1e23._.js @@ -12,7 +12,7 @@ console.log(`I like ${(0, __TURBOPACK__imported__module__$5b$project$5d2f$turbop "use strict"; __turbopack_context__.s({ - "getCat": (()=>getCat) + "getCat": ()=>getCat }); let cat = "cat"; let dog = "dog"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_d33fdf1c._.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_d33fdf1c._.js index 07840dec40daf..4708b4cb155ee 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_d33fdf1c._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_d33fdf1c._.js @@ -17,7 +17,7 @@ const proc = (0, __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$cr "use strict"; __turbopack_context__.s({ - "spawn": (()=>spawn) + "spawn": ()=>spawn }); function spawn(cmd, args) { // diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_bf21d136._.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_bf21d136._.js index c3efc07529f42..cd177690c571a 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_bf21d136._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/4e721_crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_bf21d136._.js @@ -15,7 +15,7 @@ let x = (0, __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "spawn": (()=>spawn) + "spawn": ()=>spawn }); function spawn(cmd, args) { // diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js index eebf4dc804213..56733ee834188 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js @@ -13,6 +13,22 @@ const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag; function defineProp(obj, name, options) { if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options); } +function getOverwrittenModule(moduleCache, id) { + let module = moduleCache[id]; + if (!module) { + // This is invoked when a module is merged into another module, thus it wasn't invoced via + // instantiateModule and the cache entry wasn't created yet. + module = { + exports: {}, + error: undefined, + loaded: false, + id, + namespaceObject: undefined + }; + moduleCache[id] = module; + } + return module; +} /** * Adds the getters to the exports object. */ function esm(exports, getters) { @@ -41,7 +57,11 @@ function defineProp(obj, name, options) { } /** * Makes the module an ESM with exports - */ function esmExport(module, exports, getters) { + */ function esmExport(module, exports, moduleCache, getters, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + exports = module.exports; + } module.namespaceObject = module.exports; esm(exports, getters); } @@ -74,16 +94,26 @@ function ensureDynamicExports(module, exports) { } /** * Dynamically exports properties from an object - */ function dynamicExport(module, exports, object) { + */ function dynamicExport(module, exports, moduleCache, object, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + exports = module.exports; + } ensureDynamicExports(module, exports); if (typeof object === 'object' && object !== null) { module[REEXPORTED_OBJECTS].push(object); } } -function exportValue(module, value) { +function exportValue(module, moduleCache, value, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + } module.exports = value; } -function exportNamespace(module, namespace) { +function exportNamespace(module, moduleCache, namespace, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + } module.exports = module.namespaceObject = namespace; } function createGetter(obj, key) { @@ -480,7 +510,15 @@ function loadChunkPath(chunkPath, source) { const chunkModules = require(resolved); for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory; + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory; + moduleFactories[moduleId] = moduleFactoryFn; + for (const otherModuleId of otherIds){ + moduleFactories[otherModuleId] = moduleFactoryFn; + } + } else { + moduleFactories[moduleId] = moduleFactory; + } } } loadedChunks.add(chunkPath); @@ -522,7 +560,15 @@ async function loadChunkAsync(source, chunkData) { const chunkModules = module1.exports; for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory; + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory; + moduleFactories[moduleId] = moduleFactoryFn; + for (const otherModuleId of otherIds){ + moduleFactories[otherModuleId] = moduleFactoryFn; + } + } else { + moduleFactories[moduleId] = moduleFactory; + } } } loadedChunks.add(chunkPath); @@ -570,21 +616,6 @@ function instantiateModule(id, source) { } throw new Error(`Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`); } - let parents; - switch(source.type){ - case 0: - parents = []; - break; - case 1: - // No need to add this module as a child of the parent module here, this - // has already been taken care of in `getOrInstantiateModuleFromParent`. - parents = [ - source.parentId - ]; - break; - default: - invariant(source, (source)=>`Unknown source type: ${source?.type}`); - } const module1 = { exports: {}, error: undefined, @@ -605,10 +636,10 @@ function instantiateModule(id, source) { y: externalImport, f: moduleContext, i: esmImport.bind(null, module1), - s: esmExport.bind(null, module1, module1.exports), - j: dynamicExport.bind(null, module1, module1.exports), - v: exportValue.bind(null, module1), - n: exportNamespace.bind(null, module1), + s: esmExport.bind(null, module1, module1.exports, moduleCache), + j: dynamicExport.bind(null, module1, module1.exports, moduleCache), + v: exportValue.bind(null, module1, moduleCache), + n: exportNamespace.bind(null, module1, moduleCache), m: module1, c: moduleCache, M: moduleFactories, diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map index 97ec7dd685132..d0e0edc12b4f9 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\ntype EsmNamespaceObject = Record\n\n// @ts-ignore Defined in `dev-base.ts`\ndeclare function getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: M\n): M\n\nconst REEXPORTED_OBJECTS = Symbol('reexported objects')\n\ntype ModuleContextMap = Record\n\ninterface ModuleContextEntry {\n id: () => ModuleId\n module: () => any\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject\n\n // async import call\n import(moduleId: ModuleId): Promise\n\n keys(): ModuleId[]\n\n resolve(moduleId: ModuleId): ModuleId\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: M\n) => M\n\ndeclare function getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\nconst toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options)\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, '__esModule', { value: true })\n if (toStringTag) defineProp(exports, toStringTag, { value: 'Module' })\n for (const key in getters) {\n const item = getters[key]\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n })\n } else {\n defineProp(exports, key, { get: item, enumerable: true })\n }\n }\n Object.seal(exports)\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports\n esm(exports, getters)\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS]\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = []\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === 'default' ||\n prop === '__esModule'\n ) {\n return Reflect.get(target, prop)\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop)\n if (value !== undefined) return value\n }\n return undefined\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target)\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== 'default' && !keys.includes(key)) keys.push(key)\n }\n }\n return keys\n },\n })\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports)\n\n if (typeof object === 'object' && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object)\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key]\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)]\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null)\n for (\n let current = raw;\n (typeof current === 'object' || typeof current === 'function') &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key)\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && 'default' in getters)) {\n getters['default'] = () => raw\n }\n\n esm(ns, getters)\n return ns\n}\n\nfunction createNS(raw: Module['exports']): EsmNamespaceObject {\n if (typeof raw === 'function') {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args)\n }\n } else {\n return Object.create(null)\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ))\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n // @ts-ignore\n typeof require === 'function'\n ? // @ts-ignore\n require\n : function require() {\n throw new Error('Unexpected use of runtime require')\n }\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n return module.exports\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map)\n }\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise)\n }\n\n return moduleContext\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === 'string' ? chunkData : chunkData.path\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === 'object' &&\n 'then' in maybePromise &&\n typeof maybePromise.then === 'function'\n )\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void\n let reject: (reason?: any) => void\n\n const promise = new Promise((res, rej) => {\n reject = rej\n resolve = res\n })\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n }\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol('turbopack queues')\nconst turbopackExports = Symbol('turbopack exports')\nconst turbopackError = Symbol('turbopack error')\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number }\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus\n}\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved\n queue.forEach((fn) => fn.queueCount--)\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()))\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void\n [turbopackExports]: Exports\n [turbopackError]?: any\n}\n\ntype AsyncModulePromise = Promise & AsyncModuleExt\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === 'object') {\n if (isAsyncModuleExt(dep)) return dep\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n })\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n }\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res\n resolveQueue(queue)\n },\n (err) => {\n obj[turbopackError] = err\n resolveQueue(queue)\n }\n )\n\n return obj\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n }\n })\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined\n\n const depQueues: Set = new Set()\n\n const { resolve, reject, promise: rawPromise } = createPromise()\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue)\n depQueues.forEach(fn)\n promise['catch'](() => {})\n },\n } satisfies AsyncModuleExt)\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v\n }\n },\n }\n\n Object.defineProperty(module, 'exports', attributes)\n Object.defineProperty(module, 'namespaceObject', attributes)\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps)\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError]\n return d[turbopackExports]\n })\n\n const { promise, resolve } = createPromise<() => Exports[]>()\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n })\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q)\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++\n q.push(fn)\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue))\n\n return fn.queueCount ? promise : getResult()\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err))\n } else {\n resolve(promise[turbopackExports])\n }\n\n resolveQueue(queue)\n }\n\n body(handleAsyncDependencies, asyncResult)\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, 'x:/')\n const values: Record = {}\n for (const key in realUrl) values[key] = (realUrl as any)[key]\n values.href = inputUrl\n values.pathname = inputUrl.replace(/[?#].*/, '')\n values.origin = values.protocol = ''\n values.toString = values.toJSON = (..._args: Array) => inputUrl\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n })\n}\n\nrelativeURL.prototype = URL.prototype\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`)\n}\n\n/**\n * A stub function to make `require` available but non-functional in ESM.\n */\nfunction requireStub(_moduleId: ModuleId): never {\n throw new Error('dynamic usage of require is not supported')\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}, - {"offset": {"line": 337, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw\n try {\n raw = await import(id)\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`)\n }\n\n if (raw && raw.__esModule && raw.default && 'default' in raw.default) {\n return interopEsm(raw.default, createNS(raw), true)\n }\n\n return raw\n}\n\nfunction externalRequire(\n id: ModuleId,\n thunk: () => any,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw\n try {\n raw = thunk()\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`)\n }\n\n if (!esm || raw.__esModule) {\n return raw\n }\n\n return interopEsm(raw, createNS(raw), true)\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[]\n }\n) => {\n return require.resolve(id, options)\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAEpD,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,KAAK;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,KAAgB,EAChB,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM;IACR,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,KAAK;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B","ignoreList":[0]}}, - {"offset": {"line": 376, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\ndeclare var RUNTIME_PUBLIC_PATH: string\ndeclare var RELATIVE_ROOT_PATH: string\ndeclare var ASSET_PREFIX: string\n\nconst path = require('path')\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, '.')\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.join(\n relativePathToRuntimeRoot,\n RELATIVE_ROOT_PATH\n)\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot)\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot)\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath)\n }\n return ABSOLUTE_ROOT\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAMpD,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,IAAI,CACtC,2BACA;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT","ignoreList":[0]}}, - {"offset": {"line": 396, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require('fs') as typeof import('fs')\n const { Readable } = require('stream') as typeof import('stream')\n\n const stream = createReadStream(path)\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n 'content-type': 'application/wasm',\n },\n })\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path)\n\n return await WebAssembly.compileStreaming(response)\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path)\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n )\n\n return instance.exports\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAEpD,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB","ignoreList":[0]}}, - {"offset": {"line": 417, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/nodejs/runtime.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime\n chunkPath: ChunkPath\n }\n | {\n type: SourceType.Parent\n parentId: ModuleId\n }\n\nprocess.env.TURBOPACK = '1'\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`\n case SourceType.Parent:\n return `parent module ${source.parentId}`\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n}\n\ntype ExternalRequire = (\n id: ModuleId,\n thunk: () => any,\n esm?: boolean\n) => Exports | EsmNamespaceObject\ntype ExternalImport = (id: ModuleId) => Promise\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n R: ResolvePathFromModule\n x: ExternalRequire\n y: ExternalImport\n}\n\ntype ModuleFactory = (\n this: Module['exports'],\n context: TurbopackNodeBuildContext\n) => undefined\n\nconst url = require('url') as typeof import('url')\nconst fs = require('fs/promises') as typeof import('fs/promises')\n\nconst moduleFactories: ModuleFactories = Object.create(null)\nconst moduleCache: ModuleCache = Object.create(null)\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId)\n const exportedPath = exported?.default ?? exported\n if (typeof exportedPath !== 'string') {\n return exported as any\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length)\n const resolved = path.resolve(RUNTIME_ROOT, strippedAssetPrefix)\n\n return url.pathToFileURL(resolved).href\n }\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === 'string') {\n return loadChunkPath(chunkData, source)\n } else {\n return loadChunkPath(chunkData.path, source)\n }\n}\n\nconst loadedChunks = new Set()\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!isJs(chunkPath)) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return\n }\n\n if (loadedChunks.has(chunkPath)) {\n return\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n const chunkModules: ModuleFactories = require(resolved)\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory\n }\n }\n loadedChunks.add(chunkPath)\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`\n }\n\n throw new Error(errorMessage, {\n cause: e,\n })\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n const chunkPath = typeof chunkData === 'string' ? chunkData : chunkData.path\n if (!isJs(chunkPath)) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return\n }\n\n if (loadedChunks.has(chunkPath)) {\n return\n }\n\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n try {\n const contents = await fs.readFile(resolved, 'utf-8')\n\n const localRequire = (id: string) => {\n let resolvedId = require.resolve(id, { paths: [path.dirname(resolved)] })\n return require(resolvedId)\n }\n const module = {\n exports: {},\n }\n // TODO: Use vm.runInThisContext once our minimal supported Node.js version includes https://github.com/nodejs/node/pull/52153\n // eslint-disable-next-line no-eval -- Can't use vm.runInThisContext due to https://github.com/nodejs/node/issues/52102\n ;(0, eval)(\n '(function(module, exports, require, __dirname, __filename) {' +\n contents +\n '\\n})' +\n '\\n//# sourceURL=' +\n url.pathToFileURL(resolved)\n )(module, module.exports, localRequire, path.dirname(resolved), resolved)\n\n const chunkModules: ModuleFactories = module.exports\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory\n }\n }\n loadedChunks.add(chunkPath)\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`\n }\n\n throw new Error(errorMessage, {\n cause: e,\n })\n }\n}\n\nasync function loadChunkAsyncByUrl(source: SourceInfo, chunkUrl: string) {\n const path = url.fileURLToPath(new URL(chunkUrl, RUNTIME_ROOT)) as ChunkPath\n return loadChunkAsync(source, path)\n}\n\nfunction loadWebAssembly(\n chunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module,\n imports: WebAssembly.Imports\n) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n return instantiateWebAssemblyFromPath(resolved, imports)\n}\n\nfunction loadWebAssemblyModule(\n chunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module\n) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n return compileWebAssemblyFromPath(resolved)\n}\n\nfunction getWorkerBlobURL(_chunks: ChunkPath[]): string {\n throw new Error('Worker blobs are not implemented yet for Node.js')\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id]\n if (typeof moduleFactory !== 'function') {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n )\n }\n\n let parents: ModuleId[]\n switch (source.type) {\n case SourceType.Runtime:\n parents = []\n break\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId]\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n namespaceObject: undefined,\n }\n moduleCache[id] = module\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module)\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n L: loadChunkAsyncByUrl.bind(null, {\n type: SourceType.Parent,\n parentId: id,\n }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n b: getWorkerBlobURL,\n z: requireStub,\n })\n } catch (error) {\n module.error = error as any\n throw error\n }\n\n module.loaded = true\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject)\n }\n\n return module\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\n// @ts-ignore\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id]\n\n if (module) {\n return module\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n })\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\n// @ts-ignore TypeScript doesn't separate this module space from the browser runtime\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId]\n if (module) {\n if (module.error) {\n throw module.error\n }\n return module\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath)\n}\n\nconst regexJsUrl = /\\.js(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.\n */\nfunction isJs(chunkUrlOrPath: ChunkUrl | ChunkPath): boolean {\n return regexJsUrl.test(chunkUrlOrPath)\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}] + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\ntype EsmNamespaceObject = Record\n\n// @ts-ignore Defined in `dev-base.ts`\ndeclare function getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: M\n): M\n\nconst REEXPORTED_OBJECTS = Symbol('reexported objects')\n\ntype ModuleContextMap = Record\n\ninterface ModuleContextEntry {\n id: () => ModuleId\n module: () => any\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject\n\n // async import call\n import(moduleId: ModuleId): Promise\n\n keys(): ModuleId[]\n\n resolve(moduleId: ModuleId): ModuleId\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: M\n) => M\n\ndeclare function getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\nconst toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options)\n}\n\nfunction getOverwrittenModule(\n moduleCache: ModuleCache,\n id: ModuleId\n): Module {\n let module = moduleCache[id]\n if (!module) {\n // This is invoked when a module is merged into another module, thus it wasn't invoced via\n // instantiateModule and the cache entry wasn't created yet.\n module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n namespaceObject: undefined,\n }\n moduleCache[id] = module\n }\n return module\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, '__esModule', { value: true })\n if (toStringTag) defineProp(exports, toStringTag, { value: 'Module' })\n for (const key in getters) {\n const item = getters[key]\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n })\n } else {\n defineProp(exports, key, { get: item, enumerable: true })\n }\n }\n Object.seal(exports)\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n moduleCache: ModuleCache,\n getters: Record any>,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n exports = module.exports\n }\n module.namespaceObject = module.exports\n esm(exports, getters)\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS]\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = []\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === 'default' ||\n prop === '__esModule'\n ) {\n return Reflect.get(target, prop)\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop)\n if (value !== undefined) return value\n }\n return undefined\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target)\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== 'default' && !keys.includes(key)) keys.push(key)\n }\n }\n return keys\n },\n })\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n moduleCache: ModuleCache,\n object: Record,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n exports = module.exports\n }\n ensureDynamicExports(module, exports)\n\n if (typeof object === 'object' && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object)\n }\n}\n\nfunction exportValue(\n module: Module,\n moduleCache: ModuleCache,\n value: any,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n }\n module.exports = value\n}\n\nfunction exportNamespace(\n module: Module,\n moduleCache: ModuleCache,\n namespace: any,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n }\n module.exports = module.namespaceObject = namespace\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key]\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)]\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null)\n for (\n let current = raw;\n (typeof current === 'object' || typeof current === 'function') &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key)\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && 'default' in getters)) {\n getters['default'] = () => raw\n }\n\n esm(ns, getters)\n return ns\n}\n\nfunction createNS(raw: Module['exports']): EsmNamespaceObject {\n if (typeof raw === 'function') {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args)\n }\n } else {\n return Object.create(null)\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ))\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n // @ts-ignore\n typeof require === 'function'\n ? // @ts-ignore\n require\n : function require() {\n throw new Error('Unexpected use of runtime require')\n }\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n return module.exports\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map)\n }\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise)\n }\n\n return moduleContext\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === 'string' ? chunkData : chunkData.path\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === 'object' &&\n 'then' in maybePromise &&\n typeof maybePromise.then === 'function'\n )\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void\n let reject: (reason?: any) => void\n\n const promise = new Promise((res, rej) => {\n reject = rej\n resolve = res\n })\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n }\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol('turbopack queues')\nconst turbopackExports = Symbol('turbopack exports')\nconst turbopackError = Symbol('turbopack error')\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number }\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus\n}\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved\n queue.forEach((fn) => fn.queueCount--)\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()))\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void\n [turbopackExports]: Exports\n [turbopackError]?: any\n}\n\ntype AsyncModulePromise = Promise & AsyncModuleExt\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === 'object') {\n if (isAsyncModuleExt(dep)) return dep\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n })\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n }\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res\n resolveQueue(queue)\n },\n (err) => {\n obj[turbopackError] = err\n resolveQueue(queue)\n }\n )\n\n return obj\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n }\n })\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined\n\n const depQueues: Set = new Set()\n\n const { resolve, reject, promise: rawPromise } = createPromise()\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue)\n depQueues.forEach(fn)\n promise['catch'](() => {})\n },\n } satisfies AsyncModuleExt)\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v\n }\n },\n }\n\n Object.defineProperty(module, 'exports', attributes)\n Object.defineProperty(module, 'namespaceObject', attributes)\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps)\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError]\n return d[turbopackExports]\n })\n\n const { promise, resolve } = createPromise<() => Exports[]>()\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n })\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q)\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++\n q.push(fn)\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue))\n\n return fn.queueCount ? promise : getResult()\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err))\n } else {\n resolve(promise[turbopackExports])\n }\n\n resolveQueue(queue)\n }\n\n body(handleAsyncDependencies, asyncResult)\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, 'x:/')\n const values: Record = {}\n for (const key in realUrl) values[key] = (realUrl as any)[key]\n values.href = inputUrl\n values.pathname = inputUrl.replace(/[?#].*/, '')\n values.origin = values.protocol = ''\n values.toString = values.toJSON = (..._args: Array) => inputUrl\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n })\n}\n\nrelativeURL.prototype = URL.prototype\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`)\n}\n\n/**\n * A stub function to make `require` available but non-functional in ESM.\n */\nfunction requireStub(_moduleId: ModuleId): never {\n throw new Error('dynamic usage of require is not supported')\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,oDAAoD,GAEpD,6CAA6C;AAU7C,MAAM,qBAAqB,OAAO;AA+BlC,MAAM,iBAAiB,OAAO,SAAS,CAAC,cAAc;AACtD,MAAM,cAAc,OAAO,WAAW,eAAe,OAAO,WAAW;AAEvE,SAAS,WACP,GAAQ,EACR,IAAiB,EACjB,OAA2C;IAE3C,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,OAAO,OAAO,cAAc,CAAC,KAAK,MAAM;AACxE;AAEA,SAAS,qBACP,WAAgC,EAChC,EAAY;IAEZ,IAAI,SAAS,WAAW,CAAC,GAAG;IAC5B,IAAI,CAAC,QAAQ;QACX,0FAA0F;QAC1F,4DAA4D;QAC5D,SAAS;YACP,SAAS,CAAC;YACV,OAAO;YACP,QAAQ;YACR;YACA,iBAAiB;QACnB;QACA,WAAW,CAAC,GAAG,GAAG;IACpB;IACA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,IACP,OAAgB,EAChB,OAAoE;IAEpE,WAAW,SAAS,cAAc;QAAE,OAAO;IAAK;IAChD,IAAI,aAAa,WAAW,SAAS,aAAa;QAAE,OAAO;IAAS;IACpE,IAAK,MAAM,OAAO,QAAS;QACzB,MAAM,OAAO,OAAO,CAAC,IAAI;QACzB,IAAI,MAAM,OAAO,CAAC,OAAO;YACvB,WAAW,SAAS,KAAK;gBACvB,KAAK,IAAI,CAAC,EAAE;gBACZ,KAAK,IAAI,CAAC,EAAE;gBACZ,YAAY;YACd;QACF,OAAO;YACL,WAAW,SAAS,KAAK;gBAAE,KAAK;gBAAM,YAAY;YAAK;QACzD;IACF;IACA,OAAO,IAAI,CAAC;AACd;AAEA;;CAEC,GACD,SAAS,UACP,MAAc,EACd,OAAgB,EAChB,WAAgC,EAChC,OAAkC,EAClC,EAAwB;IAExB,IAAI,MAAM,MAAM;QACd,SAAS,qBAAqB,aAAa;QAC3C,UAAU,OAAO,OAAO;IAC1B;IACA,OAAO,eAAe,GAAG,OAAO,OAAO;IACvC,IAAI,SAAS;AACf;AAEA,SAAS,qBAAqB,MAAc,EAAE,OAAgB;IAC5D,IAAI,oBAAoB,MAAM,CAAC,mBAAmB;IAElD,IAAI,CAAC,mBAAmB;QACtB,oBAAoB,MAAM,CAAC,mBAAmB,GAAG,EAAE;QACnD,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG,IAAI,MAAM,SAAS;YAC3D,KAAI,MAAM,EAAE,IAAI;gBACd,IACE,eAAe,IAAI,CAAC,QAAQ,SAC5B,SAAS,aACT,SAAS,cACT;oBACA,OAAO,QAAQ,GAAG,CAAC,QAAQ;gBAC7B;gBACA,KAAK,MAAM,OAAO,kBAAoB;oBACpC,MAAM,QAAQ,QAAQ,GAAG,CAAC,KAAK;oBAC/B,IAAI,UAAU,WAAW,OAAO;gBAClC;gBACA,OAAO;YACT;YACA,SAAQ,MAAM;gBACZ,MAAM,OAAO,QAAQ,OAAO,CAAC;gBAC7B,KAAK,MAAM,OAAO,kBAAoB;oBACpC,KAAK,MAAM,OAAO,QAAQ,OAAO,CAAC,KAAM;wBACtC,IAAI,QAAQ,aAAa,CAAC,KAAK,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC;oBAC1D;gBACF;gBACA,OAAO;YACT;QACF;IACF;AACF;AAEA;;CAEC,GACD,SAAS,cACP,MAAc,EACd,OAAgB,EAChB,WAAgC,EAChC,MAA2B,EAC3B,EAAwB;IAExB,IAAI,MAAM,MAAM;QACd,SAAS,qBAAqB,aAAa;QAC3C,UAAU,OAAO,OAAO;IAC1B;IACA,qBAAqB,QAAQ;IAE7B,IAAI,OAAO,WAAW,YAAY,WAAW,MAAM;QACjD,MAAM,CAAC,mBAAmB,CAAE,IAAI,CAAC;IACnC;AACF;AAEA,SAAS,YACP,MAAc,EACd,WAAgC,EAChC,KAAU,EACV,EAAwB;IAExB,IAAI,MAAM,MAAM;QACd,SAAS,qBAAqB,aAAa;IAC7C;IACA,OAAO,OAAO,GAAG;AACnB;AAEA,SAAS,gBACP,MAAc,EACd,WAAgC,EAChC,SAAc,EACd,EAAwB;IAExB,IAAI,MAAM,MAAM;QACd,SAAS,qBAAqB,aAAa;IAC7C;IACA,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG;AAC5C;AAEA,SAAS,aAAa,GAAiC,EAAE,GAAoB;IAC3E,OAAO,IAAM,GAAG,CAAC,IAAI;AACvB;AAEA;;CAEC,GACD,MAAM,WAA8B,OAAO,cAAc,GACrD,CAAC,MAAQ,OAAO,cAAc,CAAC,OAC/B,CAAC,MAAQ,IAAI,SAAS;AAE1B,iDAAiD,GACjD,MAAM,kBAAkB;IAAC;IAAM,SAAS,CAAC;IAAI,SAAS,EAAE;IAAG,SAAS;CAAU;AAE9E;;;;;;CAMC,GACD,SAAS,WACP,GAAY,EACZ,EAAsB,EACtB,kBAA4B;IAE5B,MAAM,UAAsC,OAAO,MAAM,CAAC;IAC1D,IACE,IAAI,UAAU,KACd,CAAC,OAAO,YAAY,YAAY,OAAO,YAAY,UAAU,KAC7D,CAAC,gBAAgB,QAAQ,CAAC,UAC1B,UAAU,SAAS,SACnB;QACA,KAAK,MAAM,OAAO,OAAO,mBAAmB,CAAC,SAAU;YACrD,OAAO,CAAC,IAAI,GAAG,aAAa,KAAK;QACnC;IACF;IAEA,6BAA6B;IAC7B,6EAA6E;IAC7E,IAAI,CAAC,CAAC,sBAAsB,aAAa,OAAO,GAAG;QACjD,OAAO,CAAC,UAAU,GAAG,IAAM;IAC7B;IAEA,IAAI,IAAI;IACR,OAAO;AACT;AAEA,SAAS,SAAS,GAAsB;IACtC,IAAI,OAAO,QAAQ,YAAY;QAC7B,OAAO,SAAqB,GAAG,IAAW;YACxC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;QACzB;IACF,OAAO;QACL,OAAO,OAAO,MAAM,CAAC;IACvB;AACF;AAEA,SAAS,UACP,YAAoB,EACpB,EAAY;IAEZ,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IAEpC,8DAA8D;IAC9D,IAAI,OAAO,eAAe,EAAE,OAAO,OAAO,eAAe;IAEzD,iGAAiG;IACjG,MAAM,MAAM,OAAO,OAAO;IAC1B,OAAQ,OAAO,eAAe,GAAG,WAC/B,KACA,SAAS,MACT,OAAO,AAAC,IAAY,UAAU;AAElC;AAEA,+EAA+E;AAC/E,6EAA6E;AAC7E,MAAM,iBACJ,aAAa;AACb,OAAO,YAAY,aAEf,UACA,SAAS;IACP,MAAM,IAAI,MAAM;AAClB;AAEN,SAAS,gBAAgB,YAAoB,EAAE,EAAY;IACzD,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IACpC,OAAO,OAAO,OAAO;AACvB;AAEA;;CAEC,GACD,SAAS,cAAc,GAAqB;IAC1C,SAAS,cAAc,EAAY;QACjC,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM;QACvB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC9C,EAAU,IAAI,GAAG;QACnB,MAAM;IACR;IAEA,cAAc,IAAI,GAAG;QACnB,OAAO,OAAO,IAAI,CAAC;IACrB;IAEA,cAAc,OAAO,GAAG,CAAC;QACvB,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE;QACnB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC9C,EAAU,IAAI,GAAG;QACnB,MAAM;IACR;IAEA,cAAc,MAAM,GAAG,OAAO;QAC5B,OAAO,MAAO,cAAc;IAC9B;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,aAAa,SAAoB;IACxC,OAAO,OAAO,cAAc,WAAW,YAAY,UAAU,IAAI;AACnE;AAEA,SAAS,UAAmB,YAAiB;IAC3C,OACE,gBAAgB,QAChB,OAAO,iBAAiB,YACxB,UAAU,gBACV,OAAO,aAAa,IAAI,KAAK;AAEjC;AAEA,SAAS,iBAA+B,GAAM;IAC5C,OAAO,mBAAmB;AAC5B;AAEA,SAAS;IACP,IAAI;IACJ,IAAI;IAEJ,MAAM,UAAU,IAAI,QAAW,CAAC,KAAK;QACnC,SAAS;QACT,UAAU;IACZ;IAEA,OAAO;QACL;QACA,SAAS;QACT,QAAQ;IACV;AACF;AAEA,2CAA2C;AAC3C,+HAA+H;AAE/H,MAAM,kBAAkB,OAAO;AAC/B,MAAM,mBAAmB,OAAO;AAChC,MAAM,iBAAiB,OAAO;AAa9B,SAAS,aAAa,KAAkB;IACtC,IAAI,SAAS,MAAM,MAAM,QAA2B;QAClD,MAAM,MAAM;QACZ,MAAM,OAAO,CAAC,CAAC,KAAO,GAAG,UAAU;QACnC,MAAM,OAAO,CAAC,CAAC,KAAQ,GAAG,UAAU,KAAK,GAAG,UAAU,KAAK;IAC7D;AACF;AAYA,SAAS,SAAS,IAAW;IAC3B,OAAO,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;YAC3C,IAAI,iBAAiB,MAAM,OAAO;YAClC,IAAI,UAAU,MAAM;gBAClB,MAAM,QAAoB,OAAO,MAAM,CAAC,EAAE,EAAE;oBAC1C,MAAM;gBACR;gBAEA,MAAM,MAAsB;oBAC1B,CAAC,iBAAiB,EAAE,CAAC;oBACrB,CAAC,gBAAgB,EAAE,CAAC,KAAoC,GAAG;gBAC7D;gBAEA,IAAI,IAAI,CACN,CAAC;oBACC,GAAG,CAAC,iBAAiB,GAAG;oBACxB,aAAa;gBACf,GACA,CAAC;oBACC,GAAG,CAAC,eAAe,GAAG;oBACtB,aAAa;gBACf;gBAGF,OAAO;YACT;QACF;QAEA,OAAO;YACL,CAAC,iBAAiB,EAAE;YACpB,CAAC,gBAAgB,EAAE,KAAO;QAC5B;IACF;AACF;AAEA,SAAS,YACP,MAAc,EACd,IAKS,EACT,QAAiB;IAEjB,MAAM,QAAgC,WAClC,OAAO,MAAM,CAAC,EAAE,EAAE;QAAE,MAAM;IAAsB,KAChD;IAEJ,MAAM,YAA6B,IAAI;IAEvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG;IAEjD,MAAM,UAA8B,OAAO,MAAM,CAAC,YAAY;QAC5D,CAAC,iBAAiB,EAAE,OAAO,OAAO;QAClC,CAAC,gBAAgB,EAAE,CAAC;YAClB,SAAS,GAAG;YACZ,UAAU,OAAO,CAAC;YAClB,OAAO,CAAC,QAAQ,CAAC,KAAO;QAC1B;IACF;IAEA,MAAM,aAAiC;QACrC;YACE,OAAO;QACT;QACA,KAAI,CAAM;YACR,qCAAqC;YACrC,IAAI,MAAM,SAAS;gBACjB,OAAO,CAAC,iBAAiB,GAAG;YAC9B;QACF;IACF;IAEA,OAAO,cAAc,CAAC,QAAQ,WAAW;IACzC,OAAO,cAAc,CAAC,QAAQ,mBAAmB;IAEjD,SAAS,wBAAwB,IAAW;QAC1C,MAAM,cAAc,SAAS;QAE7B,MAAM,YAAY,IAChB,YAAY,GAAG,CAAC,CAAC;gBACf,IAAI,CAAC,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,eAAe;gBAC9C,OAAO,CAAC,CAAC,iBAAiB;YAC5B;QAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG;QAE7B,MAAM,KAAmB,OAAO,MAAM,CAAC,IAAM,QAAQ,YAAY;YAC/D,YAAY;QACd;QAEA,SAAS,QAAQ,CAAa;YAC5B,IAAI,MAAM,SAAS,CAAC,UAAU,GAAG,CAAC,IAAI;gBACpC,UAAU,GAAG,CAAC;gBACd,IAAI,KAAK,EAAE,MAAM,QAA6B;oBAC5C,GAAG,UAAU;oBACb,EAAE,IAAI,CAAC;gBACT;YACF;QACF;QAEA,YAAY,GAAG,CAAC,CAAC,MAAQ,GAAG,CAAC,gBAAgB,CAAC;QAE9C,OAAO,GAAG,UAAU,GAAG,UAAU;IACnC;IAEA,SAAS,YAAY,GAAS;QAC5B,IAAI,KAAK;YACP,OAAQ,OAAO,CAAC,eAAe,GAAG;QACpC,OAAO;YACL,QAAQ,OAAO,CAAC,iBAAiB;QACnC;QAEA,aAAa;IACf;IAEA,KAAK,yBAAyB;IAE9B,IAAI,SAAS,MAAM,MAAM,SAA0B;QACjD,MAAM,MAAM;IACd;AACF;AAEA;;;;;;;;;CASC,GACD,MAAM,cAAc,SAAS,YAAuB,QAAgB;IAClE,MAAM,UAAU,IAAI,IAAI,UAAU;IAClC,MAAM,SAA8B,CAAC;IACrC,IAAK,MAAM,OAAO,QAAS,MAAM,CAAC,IAAI,GAAG,AAAC,OAAe,CAAC,IAAI;IAC9D,OAAO,IAAI,GAAG;IACd,OAAO,QAAQ,GAAG,SAAS,OAAO,CAAC,UAAU;IAC7C,OAAO,MAAM,GAAG,OAAO,QAAQ,GAAG;IAClC,OAAO,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAG,QAAsB;IAC5D,IAAK,MAAM,OAAO,OAChB,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK;QAC/B,YAAY;QACZ,cAAc;QACd,OAAO,MAAM,CAAC,IAAI;IACpB;AACJ;AAEA,YAAY,SAAS,GAAG,IAAI,SAAS;AAErC;;CAEC,GACD,SAAS,UAAU,KAAY,EAAE,cAAoC;IACnE,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,eAAe,QAAQ;AACvD;AAEA;;CAEC,GACD,SAAS,YAAY,SAAmB;IACtC,MAAM,IAAI,MAAM;AAClB","ignoreList":[0]}}, + {"offset": {"line": 367, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw\n try {\n raw = await import(id)\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`)\n }\n\n if (raw && raw.__esModule && raw.default && 'default' in raw.default) {\n return interopEsm(raw.default, createNS(raw), true)\n }\n\n return raw\n}\n\nfunction externalRequire(\n id: ModuleId,\n thunk: () => any,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw\n try {\n raw = thunk()\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`)\n }\n\n if (!esm || raw.__esModule) {\n return raw\n }\n\n return interopEsm(raw, createNS(raw), true)\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[]\n }\n) => {\n return require.resolve(id, options)\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAEpD,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,KAAK;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,KAAgB,EAChB,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM;IACR,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,KAAK;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B","ignoreList":[0]}}, + {"offset": {"line": 406, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\ndeclare var RUNTIME_PUBLIC_PATH: string\ndeclare var RELATIVE_ROOT_PATH: string\ndeclare var ASSET_PREFIX: string\n\nconst path = require('path')\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, '.')\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.join(\n relativePathToRuntimeRoot,\n RELATIVE_ROOT_PATH\n)\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot)\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot)\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath)\n }\n return ABSOLUTE_ROOT\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAMpD,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,IAAI,CACtC,2BACA;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT","ignoreList":[0]}}, + {"offset": {"line": 426, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require('fs') as typeof import('fs')\n const { Readable } = require('stream') as typeof import('stream')\n\n const stream = createReadStream(path)\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n 'content-type': 'application/wasm',\n },\n })\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path)\n\n return await WebAssembly.compileStreaming(response)\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path)\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n )\n\n return instance.exports\n}\n"],"names":[],"mappings":"AAAA,oDAAoD,GAEpD,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB","ignoreList":[0]}}, + {"offset": {"line": 447, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/nodejs/runtime.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime\n chunkPath: ChunkPath\n }\n | {\n type: SourceType.Parent\n parentId: ModuleId\n }\n\nprocess.env.TURBOPACK = '1'\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`\n case SourceType.Parent:\n return `parent module ${source.parentId}`\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n}\n\ntype ExternalRequire = (\n id: ModuleId,\n thunk: () => any,\n esm?: boolean\n) => Exports | EsmNamespaceObject\ntype ExternalImport = (id: ModuleId) => Promise\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n R: ResolvePathFromModule\n x: ExternalRequire\n y: ExternalImport\n}\n\ntype ModuleFactory = (\n this: Module['exports'],\n context: TurbopackNodeBuildContext\n) => unknown\n\nconst url = require('url') as typeof import('url')\nconst fs = require('fs/promises') as typeof import('fs/promises')\n\nconst moduleFactories: ModuleFactories = Object.create(null)\nconst moduleCache: ModuleCache = Object.create(null)\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId)\n const exportedPath = exported?.default ?? exported\n if (typeof exportedPath !== 'string') {\n return exported as any\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length)\n const resolved = path.resolve(RUNTIME_ROOT, strippedAssetPrefix)\n\n return url.pathToFileURL(resolved).href\n }\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === 'string') {\n return loadChunkPath(chunkData, source)\n } else {\n return loadChunkPath(chunkData.path, source)\n }\n}\n\nconst loadedChunks = new Set()\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!isJs(chunkPath)) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return\n }\n\n if (loadedChunks.has(chunkPath)) {\n return\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n const chunkModules: CompressedModuleFactories = require(resolved)\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n if (Array.isArray(moduleFactory)) {\n let [moduleFactoryFn, otherIds] = moduleFactory\n moduleFactories[moduleId] = moduleFactoryFn\n for (const otherModuleId of otherIds) {\n moduleFactories[otherModuleId] = moduleFactoryFn\n }\n } else {\n moduleFactories[moduleId] = moduleFactory\n }\n }\n }\n loadedChunks.add(chunkPath)\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`\n }\n\n throw new Error(errorMessage, {\n cause: e,\n })\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n const chunkPath = typeof chunkData === 'string' ? chunkData : chunkData.path\n if (!isJs(chunkPath)) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return\n }\n\n if (loadedChunks.has(chunkPath)) {\n return\n }\n\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n try {\n const contents = await fs.readFile(resolved, 'utf-8')\n\n const localRequire = (id: string) => {\n let resolvedId = require.resolve(id, { paths: [path.dirname(resolved)] })\n return require(resolvedId)\n }\n const module = {\n exports: {},\n }\n // TODO: Use vm.runInThisContext once our minimal supported Node.js version includes https://github.com/nodejs/node/pull/52153\n // eslint-disable-next-line no-eval -- Can't use vm.runInThisContext due to https://github.com/nodejs/node/issues/52102\n ;(0, eval)(\n '(function(module, exports, require, __dirname, __filename) {' +\n contents +\n '\\n})' +\n '\\n//# sourceURL=' +\n url.pathToFileURL(resolved)\n )(module, module.exports, localRequire, path.dirname(resolved), resolved)\n\n const chunkModules: CompressedModuleFactories = module.exports\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n if (Array.isArray(moduleFactory)) {\n let [moduleFactoryFn, otherIds] = moduleFactory\n moduleFactories[moduleId] = moduleFactoryFn\n for (const otherModuleId of otherIds) {\n moduleFactories[otherModuleId] = moduleFactoryFn\n }\n } else {\n moduleFactories[moduleId] = moduleFactory\n }\n }\n }\n loadedChunks.add(chunkPath)\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`\n }\n\n throw new Error(errorMessage, {\n cause: e,\n })\n }\n}\n\nasync function loadChunkAsyncByUrl(source: SourceInfo, chunkUrl: string) {\n const path = url.fileURLToPath(new URL(chunkUrl, RUNTIME_ROOT)) as ChunkPath\n return loadChunkAsync(source, path)\n}\n\nfunction loadWebAssembly(\n chunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module,\n imports: WebAssembly.Imports\n) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n return instantiateWebAssemblyFromPath(resolved, imports)\n}\n\nfunction loadWebAssemblyModule(\n chunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module\n) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath)\n\n return compileWebAssemblyFromPath(resolved)\n}\n\nfunction getWorkerBlobURL(_chunks: ChunkPath[]): string {\n throw new Error('Worker blobs are not implemented yet for Node.js')\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id]\n if (typeof moduleFactory !== 'function') {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n )\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n namespaceObject: undefined,\n }\n moduleCache[id] = module\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module)\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports, moduleCache),\n j: dynamicExport.bind(null, module, module.exports, moduleCache),\n v: exportValue.bind(null, module, moduleCache),\n n: exportNamespace.bind(null, module, moduleCache),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n L: loadChunkAsyncByUrl.bind(null, {\n type: SourceType.Parent,\n parentId: id,\n }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n b: getWorkerBlobURL,\n z: requireStub,\n })\n } catch (error) {\n module.error = error as any\n throw error\n }\n\n module.loaded = true\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject)\n }\n\n return module\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\n// @ts-ignore\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id]\n\n if (module) {\n return module\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n })\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\n// @ts-ignore TypeScript doesn't separate this module space from the browser runtime\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId]\n if (module) {\n if (module.error) {\n throw module.error\n }\n return module\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath)\n}\n\nconst regexJsUrl = /\\.js(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.\n */\nfunction isJs(chunkUrlOrPath: ChunkUrl | ChunkPath): boolean {\n return regexJsUrl.test(chunkUrlOrPath)\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}] } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js index 002a256232149..c8d05d7c86f16 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js @@ -24,6 +24,22 @@ const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag; function defineProp(obj, name, options) { if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options); } +function getOverwrittenModule(moduleCache, id) { + let module = moduleCache[id]; + if (!module) { + // This is invoked when a module is merged into another module, thus it wasn't invoced via + // instantiateModule and the cache entry wasn't created yet. + module = { + exports: {}, + error: undefined, + loaded: false, + id, + namespaceObject: undefined + }; + moduleCache[id] = module; + } + return module; +} /** * Adds the getters to the exports object. */ function esm(exports, getters) { @@ -52,7 +68,11 @@ function defineProp(obj, name, options) { } /** * Makes the module an ESM with exports - */ function esmExport(module, exports, getters) { + */ function esmExport(module, exports, moduleCache, getters, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + exports = module.exports; + } module.namespaceObject = module.exports; esm(exports, getters); } @@ -85,16 +105,26 @@ function ensureDynamicExports(module, exports) { } /** * Dynamically exports properties from an object - */ function dynamicExport(module, exports, object) { + */ function dynamicExport(module, exports, moduleCache, object, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + exports = module.exports; + } ensureDynamicExports(module, exports); if (typeof object === 'object' && object !== null) { module[REEXPORTED_OBJECTS].push(object); } } -function exportValue(module, value) { +function exportValue(module, moduleCache, value, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + } module.exports = value; } -function exportNamespace(module, namespace) { +function exportNamespace(module, moduleCache, namespace, id) { + if (id != null) { + module = getOverwrittenModule(moduleCache, id); + } module.exports = module.namespaceObject = namespace; } function createGetter(obj, key) { @@ -575,7 +605,15 @@ function registerChunk([chunkScript, chunkModules, runtimeParams]) { const chunkPath = getPathFromScript(chunkScript); for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ if (!moduleFactories[moduleId]) { - moduleFactories[moduleId] = moduleFactory; + if (Array.isArray(moduleFactory)) { + let [moduleFactoryFn, otherIds] = moduleFactory; + moduleFactories[moduleId] = moduleFactoryFn; + for (const otherModuleId of otherIds){ + moduleFactories[otherModuleId] = moduleFactoryFn; + } + } else { + moduleFactories[moduleId] = moduleFactory; + } } addModuleToChunk(moduleId, chunkPath); } @@ -731,10 +769,10 @@ function instantiateModule(id, source) { t: runtimeRequire, f: moduleContext, i: esmImport.bind(null, module), - s: esmExport.bind(null, module, module.exports), - j: dynamicExport.bind(null, module, module.exports), - v: exportValue.bind(null, module), - n: exportNamespace.bind(null, module), + s: esmExport.bind(null, module, module.exports, devModuleCache), + j: dynamicExport.bind(null, module, module.exports, devModuleCache), + v: exportValue.bind(null, module, devModuleCache), + n: exportNamespace.bind(null, module, devModuleCache), m: module, c: devModuleCache, M: moduleFactories, diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js.map index 3937c57789bce..7676101efef90 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js.map +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/b1abf_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_75df6705.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\ntype EsmNamespaceObject = Record\n\n// @ts-ignore Defined in `dev-base.ts`\ndeclare function getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: M\n): M\n\nconst REEXPORTED_OBJECTS = Symbol('reexported objects')\n\ntype ModuleContextMap = Record\n\ninterface ModuleContextEntry {\n id: () => ModuleId\n module: () => any\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject\n\n // async import call\n import(moduleId: ModuleId): Promise\n\n keys(): ModuleId[]\n\n resolve(moduleId: ModuleId): ModuleId\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: M\n) => M\n\ndeclare function getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\nconst toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options)\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, '__esModule', { value: true })\n if (toStringTag) defineProp(exports, toStringTag, { value: 'Module' })\n for (const key in getters) {\n const item = getters[key]\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n })\n } else {\n defineProp(exports, key, { get: item, enumerable: true })\n }\n }\n Object.seal(exports)\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports\n esm(exports, getters)\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS]\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = []\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === 'default' ||\n prop === '__esModule'\n ) {\n return Reflect.get(target, prop)\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop)\n if (value !== undefined) return value\n }\n return undefined\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target)\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== 'default' && !keys.includes(key)) keys.push(key)\n }\n }\n return keys\n },\n })\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports)\n\n if (typeof object === 'object' && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object)\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key]\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)]\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null)\n for (\n let current = raw;\n (typeof current === 'object' || typeof current === 'function') &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key)\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && 'default' in getters)) {\n getters['default'] = () => raw\n }\n\n esm(ns, getters)\n return ns\n}\n\nfunction createNS(raw: Module['exports']): EsmNamespaceObject {\n if (typeof raw === 'function') {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args)\n }\n } else {\n return Object.create(null)\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ))\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n // @ts-ignore\n typeof require === 'function'\n ? // @ts-ignore\n require\n : function require() {\n throw new Error('Unexpected use of runtime require')\n }\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n return module.exports\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map)\n }\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise)\n }\n\n return moduleContext\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === 'string' ? chunkData : chunkData.path\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === 'object' &&\n 'then' in maybePromise &&\n typeof maybePromise.then === 'function'\n )\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void\n let reject: (reason?: any) => void\n\n const promise = new Promise((res, rej) => {\n reject = rej\n resolve = res\n })\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n }\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol('turbopack queues')\nconst turbopackExports = Symbol('turbopack exports')\nconst turbopackError = Symbol('turbopack error')\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number }\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus\n}\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved\n queue.forEach((fn) => fn.queueCount--)\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()))\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void\n [turbopackExports]: Exports\n [turbopackError]?: any\n}\n\ntype AsyncModulePromise = Promise & AsyncModuleExt\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === 'object') {\n if (isAsyncModuleExt(dep)) return dep\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n })\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n }\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res\n resolveQueue(queue)\n },\n (err) => {\n obj[turbopackError] = err\n resolveQueue(queue)\n }\n )\n\n return obj\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n }\n })\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined\n\n const depQueues: Set = new Set()\n\n const { resolve, reject, promise: rawPromise } = createPromise()\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue)\n depQueues.forEach(fn)\n promise['catch'](() => {})\n },\n } satisfies AsyncModuleExt)\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v\n }\n },\n }\n\n Object.defineProperty(module, 'exports', attributes)\n Object.defineProperty(module, 'namespaceObject', attributes)\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps)\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError]\n return d[turbopackExports]\n })\n\n const { promise, resolve } = createPromise<() => Exports[]>()\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n })\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q)\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++\n q.push(fn)\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue))\n\n return fn.queueCount ? promise : getResult()\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err))\n } else {\n resolve(promise[turbopackExports])\n }\n\n resolveQueue(queue)\n }\n\n body(handleAsyncDependencies, asyncResult)\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, 'x:/')\n const values: Record = {}\n for (const key in realUrl) values[key] = (realUrl as any)[key]\n values.href = inputUrl\n values.pathname = inputUrl.replace(/[?#].*/, '')\n values.origin = values.protocol = ''\n values.toString = values.toJSON = (..._args: Array) => inputUrl\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n })\n}\n\nrelativeURL.prototype = URL.prototype\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`)\n}\n\n/**\n * A stub function to make `require` available but non-functional in ESM.\n */\nfunction requireStub(_moduleId: ModuleId): never {\n throw new Error('dynamic usage of require is not supported')\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}, - {"offset": {"line": 348, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/base/runtime-base.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n\n// Used in WebWorkers to tell the runtime about the chunk base path\ndeclare var TURBOPACK_WORKER_LOCATION: string\n// Used in WebWorkers to tell the runtime about the current chunk url since it can't be detected via document.currentScript\n// Note it's stored in reversed order to use push and pop\ndeclare var TURBOPACK_NEXT_CHUNK_URLS: ChunkUrl[] | undefined\n\n// Injected by rust code\ndeclare var CHUNK_BASE_PATH: string\ndeclare var CHUNK_SUFFIX_PATH: string\n\n// Provided by build or dev base\ndeclare function instantiateModule(id: ModuleId, source: SourceInfo): Module\n\ntype RuntimeParams = {\n otherChunks: ChunkData[]\n runtimeModuleIds: ModuleId[]\n}\n\ntype ChunkRegistration = [\n chunkPath: ChunkScript,\n chunkModules: ModuleFactories,\n params: RuntimeParams | undefined,\n]\n\ntype ChunkList = {\n script: ChunkListScript\n chunks: ChunkData[]\n source: 'entry' | 'dynamic'\n}\n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n /**\n * The module was instantiated because it was included in a chunk's hot module\n * update.\n */\n Update = 2,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime\n chunkPath: ChunkPath\n }\n | {\n type: SourceType.Parent\n parentId: ModuleId\n }\n | {\n type: SourceType.Update\n parents?: ModuleId[]\n }\n\ninterface RuntimeBackend {\n registerChunk: (chunkPath: ChunkPath, params?: RuntimeParams) => void\n loadChunk: (chunkUrl: ChunkUrl, source: SourceInfo) => Promise\n}\n\ninterface DevRuntimeBackend {\n reloadChunk?: (chunkUrl: ChunkUrl) => Promise\n unloadChunk?: (chunkUrl: ChunkUrl) => void\n restart: () => void\n}\n\nconst moduleFactories: ModuleFactories = Object.create(null)\n/**\n * Module IDs that are instantiated as part of the runtime of a chunk.\n */\nconst runtimeModules: Set = new Set()\n/**\n * Map from module ID to the chunks that contain this module.\n *\n * In HMR, we need to keep track of which modules are contained in which so\n * chunks. This is so we don't eagerly dispose of a module when it is removed\n * from chunk A, but still exists in chunk B.\n */\nconst moduleChunksMap: Map> = new Map()\n/**\n * Map from a chunk path to all modules it contains.\n */\nconst chunkModulesMap: Map> = new Map()\n/**\n * Chunk lists that contain a runtime. When these chunk lists receive an update\n * that can't be reconciled with the current state of the page, we need to\n * reload the runtime entirely.\n */\nconst runtimeChunkLists: Set = new Set()\n/**\n * Map from a chunk list to the chunk paths it contains.\n */\nconst chunkListChunksMap: Map> = new Map()\n/**\n * Map from a chunk path to the chunk lists it belongs to.\n */\nconst chunkChunkListsMap: Map> = new Map()\n\nconst availableModules: Map | true> = new Map()\n\nconst availableModuleChunks: Map | true> = new Map()\n\nasync function loadChunk(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n if (typeof chunkData === 'string') {\n return loadChunkPath(source, chunkData)\n }\n\n const includedList = chunkData.included || []\n const modulesPromises = includedList.map((included) => {\n if (moduleFactories[included]) return true\n return availableModules.get(included)\n })\n if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) {\n // When all included items are already loaded or loading, we can skip loading ourselves\n return Promise.all(modulesPromises)\n }\n\n const includedModuleChunksList = chunkData.moduleChunks || []\n const moduleChunksPromises = includedModuleChunksList\n .map((included) => {\n // TODO(alexkirsz) Do we need this check?\n // if (moduleFactories[included]) return true;\n return availableModuleChunks.get(included)\n })\n .filter((p) => p)\n\n let promise\n if (moduleChunksPromises.length > 0) {\n // Some module chunks are already loaded or loading.\n\n if (moduleChunksPromises.length === includedModuleChunksList.length) {\n // When all included module chunks are already loaded or loading, we can skip loading ourselves\n return Promise.all(moduleChunksPromises)\n }\n\n const moduleChunksToLoad: Set = new Set()\n for (const moduleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(moduleChunk)) {\n moduleChunksToLoad.add(moduleChunk)\n }\n }\n\n for (const moduleChunkToLoad of moduleChunksToLoad) {\n const promise = loadChunkPath(source, moduleChunkToLoad)\n\n availableModuleChunks.set(moduleChunkToLoad, promise)\n\n moduleChunksPromises.push(promise)\n }\n\n promise = Promise.all(moduleChunksPromises)\n } else {\n promise = loadChunkPath(source, chunkData.path)\n\n // Mark all included module chunks as loading if they are not already loaded or loading.\n for (const includedModuleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(includedModuleChunk)) {\n availableModuleChunks.set(includedModuleChunk, promise)\n }\n }\n }\n\n for (const included of includedList) {\n if (!availableModules.has(included)) {\n // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier.\n // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway.\n availableModules.set(included, promise)\n }\n }\n\n return promise\n}\n\nasync function loadChunkByUrl(source: SourceInfo, chunkUrl: ChunkUrl) {\n try {\n await BACKEND.loadChunk(chunkUrl, source)\n } catch (error) {\n let loadReason\n switch (source.type) {\n case SourceType.Runtime:\n loadReason = `as a runtime dependency of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n loadReason = `from module ${source.parentId}`\n break\n case SourceType.Update:\n loadReason = 'from an HMR update'\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Failed to load chunk ${chunkUrl} ${loadReason}${\n error ? `: ${error}` : ''\n }`,\n error\n ? {\n cause: error,\n }\n : undefined\n )\n }\n}\n\nasync function loadChunkPath(\n source: SourceInfo,\n chunkPath: ChunkPath\n): Promise {\n const url = getChunkRelativeUrl(chunkPath)\n return loadChunkByUrl(source, url)\n}\n\n/**\n * Returns an absolute url to an asset.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId)\n return exported?.default ?? exported\n }\n}\n\n/**\n * no-op for browser\n * @param modulePath\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n return `/ROOT/${modulePath ?? ''}`\n}\n\n/**\n * Returns a blob URL for the worker.\n * @param chunks list of chunks to load\n */\nfunction getWorkerBlobURL(chunks: ChunkPath[]): string {\n // It is important to reverse the array so when bootstrapping we can infer what chunk is being\n // evaluated by poping urls off of this array. See `getPathFromScript`\n let bootstrap = `self.TURBOPACK_WORKER_LOCATION = ${JSON.stringify(location.origin)};\nself.TURBOPACK_NEXT_CHUNK_URLS = ${JSON.stringify(chunks.reverse().map(getChunkRelativeUrl), null, 2)};\nimportScripts(...self.TURBOPACK_NEXT_CHUNK_URLS.map(c => self.TURBOPACK_WORKER_LOCATION + c).reverse());`\n let blob = new Blob([bootstrap], { type: 'text/javascript' })\n return URL.createObjectURL(blob)\n}\n\n/**\n * Adds a module to a chunk.\n */\nfunction addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) {\n let moduleChunks = moduleChunksMap.get(moduleId)\n if (!moduleChunks) {\n moduleChunks = new Set([chunkPath])\n moduleChunksMap.set(moduleId, moduleChunks)\n } else {\n moduleChunks.add(chunkPath)\n }\n\n let chunkModules = chunkModulesMap.get(chunkPath)\n if (!chunkModules) {\n chunkModules = new Set([moduleId])\n chunkModulesMap.set(chunkPath, chunkModules)\n } else {\n chunkModules.add(moduleId)\n }\n}\n\n/**\n * Returns the first chunk that included a module.\n * This is used by the Node.js backend, hence why it's marked as unused in this\n * file.\n */\nfunction getFirstModuleChunk(moduleId: ModuleId) {\n const moduleChunkPaths = moduleChunksMap.get(moduleId)\n if (moduleChunkPaths == null) {\n return null\n }\n\n return moduleChunkPaths.values().next().value\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n/**\n * Returns the URL relative to the origin where a chunk can be fetched from.\n */\nfunction getChunkRelativeUrl(chunkPath: ChunkPath | ChunkListPath): ChunkUrl {\n return `${CHUNK_BASE_PATH}${chunkPath\n .split('/')\n .map((p) => encodeURIComponent(p))\n .join('/')}${CHUNK_SUFFIX_PATH}` as ChunkUrl\n}\n\n/**\n * Return the ChunkPath from a ChunkScript.\n */\nfunction getPathFromScript(chunkScript: ChunkPath | ChunkScript): ChunkPath\nfunction getPathFromScript(\n chunkScript: ChunkListPath | ChunkListScript\n): ChunkListPath\nfunction getPathFromScript(\n chunkScript: ChunkPath | ChunkListPath | ChunkScript | ChunkListScript\n): ChunkPath | ChunkListPath {\n if (typeof chunkScript === 'string') {\n return chunkScript as ChunkPath | ChunkListPath\n }\n const chunkUrl =\n typeof TURBOPACK_NEXT_CHUNK_URLS !== 'undefined'\n ? TURBOPACK_NEXT_CHUNK_URLS.pop()!\n : chunkScript.getAttribute('src')!\n const src = decodeURIComponent(chunkUrl.replace(/[?#].*$/, ''))\n const path = src.startsWith(CHUNK_BASE_PATH)\n ? src.slice(CHUNK_BASE_PATH.length)\n : src\n return path as ChunkPath | ChunkListPath\n}\n\n/**\n * Marks a chunk list as a runtime chunk list. There can be more than one\n * runtime chunk list. For instance, integration tests can have multiple chunk\n * groups loaded at runtime, each with its own chunk list.\n */\nfunction markChunkListAsRuntime(chunkListPath: ChunkListPath) {\n runtimeChunkLists.add(chunkListPath)\n}\n\nfunction registerChunk([\n chunkScript,\n chunkModules,\n runtimeParams,\n]: ChunkRegistration) {\n const chunkPath = getPathFromScript(chunkScript)\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory\n }\n addModuleToChunk(moduleId, chunkPath)\n }\n\n return BACKEND.registerChunk(chunkPath, runtimeParams)\n}\n\nconst regexJsUrl = /\\.js(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.\n */\nfunction isJs(chunkUrlOrPath: ChunkUrl | ChunkPath): boolean {\n return regexJsUrl.test(chunkUrlOrPath)\n}\n\nconst regexCssUrl = /\\.css(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .css, optionally followed by ?query or #fragment.\n */\nfunction isCss(chunkUrl: ChunkUrl): boolean {\n return regexCssUrl.test(chunkUrl)\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}, - {"offset": {"line": 595, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/base/dev-base.ts"],"sourcesContent":["/// \n/// \n/// \n\n/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\nconst devModuleCache: ModuleCache = Object.create(null)\n\n// This file must not use `import` and `export` statements. Otherwise, it\n// becomes impossible to augment interfaces declared in ``d files\n// (e.g. `Module`). Hence, the need for `import()` here.\ntype RefreshRuntimeGlobals =\n import('@next/react-refresh-utils/dist/runtime').RefreshRuntimeGlobals\n\ndeclare var $RefreshHelpers$: RefreshRuntimeGlobals['$RefreshHelpers$']\ndeclare var $RefreshReg$: RefreshRuntimeGlobals['$RefreshReg$']\ndeclare var $RefreshSig$: RefreshRuntimeGlobals['$RefreshSig$']\ndeclare var $RefreshInterceptModuleExecution$: RefreshRuntimeGlobals['$RefreshInterceptModuleExecution$']\n\ntype RefreshContext = {\n register: RefreshRuntimeGlobals['$RefreshReg$']\n signature: RefreshRuntimeGlobals['$RefreshSig$']\n registerExports: typeof registerExportsAndSetupBoundaryForReactRefresh\n}\n\ntype RefreshHelpers = RefreshRuntimeGlobals['$RefreshHelpers$']\n\ninterface TurbopackDevBaseContext extends TurbopackBaseContext {\n k: RefreshContext\n R: ResolvePathFromModule\n}\n\ninterface TurbopackDevContext extends TurbopackDevBaseContext {}\n\ntype ModuleFactory = (\n this: Module['exports'],\n context: TurbopackDevBaseContext\n) => undefined\n\ninterface DevRuntimeBackend {\n reloadChunk?: (chunkUrl: ChunkUrl) => Promise\n unloadChunk?: (chunkUrl: ChunkUrl) => void\n restart: () => void\n}\n\nclass UpdateApplyError extends Error {\n name = 'UpdateApplyError'\n\n dependencyChain: string[]\n\n constructor(message: string, dependencyChain: string[]) {\n super(message)\n this.dependencyChain = dependencyChain\n }\n}\n\n/**\n * Maps module IDs to persisted data between executions of their hot module\n * implementation (`hot.data`).\n */\nconst moduleHotData: Map = new Map()\n/**\n * Maps module instances to their hot module state.\n */\nconst moduleHotState: Map = new Map()\n/**\n * Modules that call `module.hot.invalidate()` (while being updated).\n */\nconst queuedInvalidatedModules: Set = new Set()\n\n/**\n * Gets or instantiates a runtime module.\n */\n// @ts-ignore\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = devModuleCache[moduleId]\n if (module) {\n if (module.error) {\n throw module.error\n }\n return module\n }\n\n // @ts-ignore\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\n// @ts-ignore Defined in `runtime-utils.ts`\nconst getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent<\n HotModule\n> = (id, sourceModule) => {\n if (!sourceModule.hot.active) {\n console.warn(\n `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`\n )\n }\n\n const module = devModuleCache[id]\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id)\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id)\n }\n\n return module\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n })\n}\n\n// @ts-ignore Defined in `runtime-base.ts`\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id]\n if (typeof moduleFactory !== 'function') {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`\n break\n case SourceType.Update:\n instantiationReason = 'because of an HMR update'\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n )\n }\n\n const hotData = moduleHotData.get(id)!\n const { hot, hotState } = createModuleHot(id, hotData)\n\n let parents: ModuleId[]\n switch (source.type) {\n case SourceType.Runtime:\n runtimeModules.add(id)\n parents = []\n break\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId]\n break\n case SourceType.Update:\n parents = source.parents || []\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n\n const module: HotModule = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n hot,\n }\n\n devModuleCache[id] = module\n moduleHotState.set(module, hotState)\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id }\n\n runModuleExecutionHooks(module, (refresh) => {\n const r = commonJsRequire.bind(null, module)\n moduleFactory.call(\n module.exports,\n augmentContext({\n a: asyncModule.bind(null, module),\n e: module.exports,\n r: commonJsRequire.bind(null, module),\n t: runtimeRequire,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: devModuleCache,\n M: moduleFactories,\n l: loadChunk.bind(null, sourceInfo),\n L: loadChunkByUrl.bind(null, sourceInfo),\n w: loadWebAssembly.bind(null, sourceInfo),\n u: loadWebAssemblyModule.bind(null, sourceInfo),\n P: resolveAbsolutePath,\n U: relativeURL,\n k: refresh,\n R: createResolvePathFromModule(r),\n b: getWorkerBlobURL,\n z: requireStub,\n })\n )\n })\n } catch (error) {\n module.error = error as any\n throw error\n }\n\n module.loaded = true\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject)\n }\n\n return module\n}\n\n/**\n * NOTE(alexkirsz) Webpack has a \"module execution\" interception hook that\n * Next.js' React Refresh runtime hooks into to add module context to the\n * refresh registry.\n */\nfunction runModuleExecutionHooks(\n module: Module,\n executeModule: (ctx: RefreshContext) => void\n) {\n if (typeof globalThis.$RefreshInterceptModuleExecution$ === 'function') {\n const cleanupReactRefreshIntercept =\n globalThis.$RefreshInterceptModuleExecution$(module.id)\n try {\n executeModule({\n register: globalThis.$RefreshReg$,\n signature: globalThis.$RefreshSig$,\n registerExports: registerExportsAndSetupBoundaryForReactRefresh,\n })\n } finally {\n // Always cleanup the intercept, even if module execution failed.\n cleanupReactRefreshIntercept()\n }\n } else {\n // If the react refresh hooks are not installed we need to bind dummy functions.\n // This is expected when running in a Web Worker. It is also common in some of\n // our test environments.\n executeModule({\n register: (type, id) => {},\n signature: () => (type) => {},\n registerExports: (module, helpers) => {},\n })\n }\n}\n\n/**\n * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts\n */\nfunction registerExportsAndSetupBoundaryForReactRefresh(\n module: HotModule,\n helpers: RefreshHelpers\n) {\n const currentExports = module.exports\n const prevExports = module.hot.data.prevExports ?? null\n\n helpers.registerExportsForReactRefresh(currentExports, module.id)\n\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (helpers.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports on update, so we can compare the boundary\n // signatures.\n module.hot.dispose((data) => {\n data.prevExports = currentExports\n })\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n module.hot.accept()\n\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevExports !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (\n helpers.shouldInvalidateReactRefreshBoundary(\n helpers.getRefreshBoundarySignature(prevExports),\n helpers.getRefreshBoundarySignature(currentExports)\n )\n ) {\n module.hot.invalidate()\n } else {\n helpers.scheduleUpdate()\n }\n }\n } else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n const isNoLongerABoundary = prevExports !== null\n if (isNoLongerABoundary) {\n module.hot.invalidate()\n }\n }\n}\n\nfunction formatDependencyChain(dependencyChain: ModuleId[]): string {\n return `Dependency chain: ${dependencyChain.join(' -> ')}`\n}\n\nfunction computeOutdatedModules(\n added: Map,\n modified: Map\n): {\n outdatedModules: Set\n newModuleFactories: Map\n} {\n const newModuleFactories = new Map()\n\n for (const [moduleId, entry] of added) {\n if (entry != null) {\n newModuleFactories.set(moduleId, _eval(entry))\n }\n }\n\n const outdatedModules = computedInvalidatedModules(modified.keys())\n\n for (const [moduleId, entry] of modified) {\n newModuleFactories.set(moduleId, _eval(entry))\n }\n\n return { outdatedModules, newModuleFactories }\n}\n\nfunction computedInvalidatedModules(\n invalidated: Iterable\n): Set {\n const outdatedModules = new Set()\n\n for (const moduleId of invalidated) {\n const effect = getAffectedModuleEffects(moduleId)\n\n switch (effect.type) {\n case 'unaccepted':\n throw new UpdateApplyError(\n `cannot apply update: unaccepted module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n )\n case 'self-declined':\n throw new UpdateApplyError(\n `cannot apply update: self-declined module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n )\n case 'accepted':\n for (const outdatedModuleId of effect.outdatedModules) {\n outdatedModules.add(outdatedModuleId)\n }\n break\n // TODO(alexkirsz) Dependencies: handle dependencies effects.\n default:\n invariant(effect, (effect) => `Unknown effect type: ${effect?.type}`)\n }\n }\n\n return outdatedModules\n}\n\nfunction computeOutdatedSelfAcceptedModules(\n outdatedModules: Iterable\n): { moduleId: ModuleId; errorHandler: true | Function }[] {\n const outdatedSelfAcceptedModules: {\n moduleId: ModuleId\n errorHandler: true | Function\n }[] = []\n for (const moduleId of outdatedModules) {\n const module = devModuleCache[moduleId]\n const hotState = moduleHotState.get(module)!\n if (module && hotState.selfAccepted && !hotState.selfInvalidated) {\n outdatedSelfAcceptedModules.push({\n moduleId,\n errorHandler: hotState.selfAccepted,\n })\n }\n }\n return outdatedSelfAcceptedModules\n}\n\n/**\n * Adds, deletes, and moves modules between chunks. This must happen before the\n * dispose phase as it needs to know which modules were removed from all chunks,\n * which we can only compute *after* taking care of added and moved modules.\n */\nfunction updateChunksPhase(\n chunksAddedModules: Map>,\n chunksDeletedModules: Map>\n): { disposedModules: Set } {\n for (const [chunkPath, addedModuleIds] of chunksAddedModules) {\n for (const moduleId of addedModuleIds) {\n addModuleToChunk(moduleId, chunkPath)\n }\n }\n\n const disposedModules: Set = new Set()\n for (const [chunkPath, addedModuleIds] of chunksDeletedModules) {\n for (const moduleId of addedModuleIds) {\n if (removeModuleFromChunk(moduleId, chunkPath)) {\n disposedModules.add(moduleId)\n }\n }\n }\n\n return { disposedModules }\n}\n\nfunction disposePhase(\n outdatedModules: Iterable,\n disposedModules: Iterable\n): { outdatedModuleParents: Map> } {\n for (const moduleId of outdatedModules) {\n disposeModule(moduleId, 'replace')\n }\n\n for (const moduleId of disposedModules) {\n disposeModule(moduleId, 'clear')\n }\n\n // Removing modules from the module cache is a separate step.\n // We also want to keep track of previous parents of the outdated modules.\n const outdatedModuleParents = new Map()\n for (const moduleId of outdatedModules) {\n const oldModule = devModuleCache[moduleId]\n outdatedModuleParents.set(moduleId, oldModule?.parents)\n delete devModuleCache[moduleId]\n }\n\n // TODO(alexkirsz) Dependencies: remove outdated dependency from module\n // children.\n\n return { outdatedModuleParents }\n}\n\n/**\n * Disposes of an instance of a module.\n *\n * Returns the persistent hot data that should be kept for the next module\n * instance.\n *\n * NOTE: mode = \"replace\" will not remove modules from the devModuleCache\n * This must be done in a separate step afterwards.\n * This is important because all modules need to be disposed to update the\n * parent/child relationships before they are actually removed from the devModuleCache.\n * If this was done in this method, the following disposeModule calls won't find\n * the module from the module id in the cache.\n */\nfunction disposeModule(moduleId: ModuleId, mode: 'clear' | 'replace') {\n const module = devModuleCache[moduleId]\n if (!module) {\n return\n }\n\n const hotState = moduleHotState.get(module)!\n const data = {}\n\n // Run the `hot.dispose` handler, if any, passing in the persistent\n // `hot.data` object.\n for (const disposeHandler of hotState.disposeHandlers) {\n disposeHandler(data)\n }\n\n // This used to warn in `getOrInstantiateModuleFromParent` when a disposed\n // module is still importing other modules.\n module.hot.active = false\n\n moduleHotState.delete(module)\n\n // TODO(alexkirsz) Dependencies: delete the module from outdated deps.\n\n // Remove the disposed module from its children's parent list.\n // It will be added back once the module re-instantiates and imports its\n // children again.\n for (const childId of module.children) {\n const child = devModuleCache[childId]\n if (!child) {\n continue\n }\n\n const idx = child.parents.indexOf(module.id)\n if (idx >= 0) {\n child.parents.splice(idx, 1)\n }\n }\n\n switch (mode) {\n case 'clear':\n delete devModuleCache[module.id]\n moduleHotData.delete(module.id)\n break\n case 'replace':\n moduleHotData.set(module.id, data)\n break\n default:\n invariant(mode, (mode) => `invalid mode: ${mode}`)\n }\n}\n\nfunction applyPhase(\n outdatedSelfAcceptedModules: {\n moduleId: ModuleId\n errorHandler: true | Function\n }[],\n newModuleFactories: Map,\n outdatedModuleParents: Map>,\n reportError: (err: any) => void\n) {\n // Update module factories.\n for (const [moduleId, factory] of newModuleFactories.entries()) {\n moduleFactories[moduleId] = factory\n }\n\n // TODO(alexkirsz) Run new runtime entries here.\n\n // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps.\n\n // Re-instantiate all outdated self-accepted modules.\n for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) {\n try {\n instantiateModule(moduleId, {\n type: SourceType.Update,\n parents: outdatedModuleParents.get(moduleId),\n })\n } catch (err) {\n if (typeof errorHandler === 'function') {\n try {\n errorHandler(err, { moduleId, module: devModuleCache[moduleId] })\n } catch (err2) {\n reportError(err2)\n reportError(err)\n }\n } else {\n reportError(err)\n }\n }\n }\n}\n\nfunction applyUpdate(update: PartialUpdate) {\n switch (update.type) {\n case 'ChunkListUpdate':\n applyChunkListUpdate(update)\n break\n default:\n invariant(update, (update) => `Unknown update type: ${update.type}`)\n }\n}\n\nfunction applyChunkListUpdate(update: ChunkListUpdate) {\n if (update.merged != null) {\n for (const merged of update.merged) {\n switch (merged.type) {\n case 'EcmascriptMergedUpdate':\n applyEcmascriptMergedUpdate(merged)\n break\n default:\n invariant(merged, (merged) => `Unknown merged type: ${merged.type}`)\n }\n }\n }\n\n if (update.chunks != null) {\n for (const [chunkPath, chunkUpdate] of Object.entries(\n update.chunks\n ) as Array<[ChunkPath, ChunkUpdate]>) {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n\n switch (chunkUpdate.type) {\n case 'added':\n BACKEND.loadChunk(chunkUrl, { type: SourceType.Update })\n break\n case 'total':\n DEV_BACKEND.reloadChunk?.(chunkUrl)\n break\n case 'deleted':\n DEV_BACKEND.unloadChunk?.(chunkUrl)\n break\n case 'partial':\n invariant(\n chunkUpdate.instruction,\n (instruction) =>\n `Unknown partial instruction: ${JSON.stringify(instruction)}.`\n )\n break\n default:\n invariant(\n chunkUpdate,\n (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}`\n )\n }\n }\n }\n}\n\nfunction applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) {\n const { entries = {}, chunks = {} } = update\n const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(\n entries,\n chunks\n )\n const { outdatedModules, newModuleFactories } = computeOutdatedModules(\n added,\n modified\n )\n const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted)\n\n applyInternal(outdatedModules, disposedModules, newModuleFactories)\n}\n\nfunction applyInvalidatedModules(outdatedModules: Set) {\n if (queuedInvalidatedModules.size > 0) {\n computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => {\n outdatedModules.add(moduleId)\n })\n\n queuedInvalidatedModules.clear()\n }\n\n return outdatedModules\n}\n\nfunction applyInternal(\n outdatedModules: Set,\n disposedModules: Iterable,\n newModuleFactories: Map\n) {\n outdatedModules = applyInvalidatedModules(outdatedModules)\n\n const outdatedSelfAcceptedModules =\n computeOutdatedSelfAcceptedModules(outdatedModules)\n\n const { outdatedModuleParents } = disposePhase(\n outdatedModules,\n disposedModules\n )\n\n // we want to continue on error and only throw the error after we tried applying all updates\n let error: any\n\n function reportError(err: any) {\n if (!error) error = err\n }\n\n applyPhase(\n outdatedSelfAcceptedModules,\n newModuleFactories,\n outdatedModuleParents,\n reportError\n )\n\n if (error) {\n throw error\n }\n\n if (queuedInvalidatedModules.size > 0) {\n applyInternal(new Set(), [], new Map())\n }\n}\n\nfunction computeChangedModules(\n entries: Record,\n updates: Record\n): {\n added: Map\n modified: Map\n deleted: Set\n chunksAdded: Map>\n chunksDeleted: Map>\n} {\n const chunksAdded = new Map()\n const chunksDeleted = new Map()\n const added: Map = new Map()\n const modified = new Map()\n const deleted: Set = new Set()\n\n for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates) as Array<\n [ChunkPath, EcmascriptMergedChunkUpdate]\n >) {\n switch (mergedChunkUpdate.type) {\n case 'added': {\n const updateAdded = new Set(mergedChunkUpdate.modules)\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId])\n }\n chunksAdded.set(chunkPath, updateAdded)\n break\n }\n case 'deleted': {\n // We could also use `mergedChunkUpdate.modules` here.\n const updateDeleted = new Set(chunkModulesMap.get(chunkPath))\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId)\n }\n chunksDeleted.set(chunkPath, updateDeleted)\n break\n }\n case 'partial': {\n const updateAdded = new Set(mergedChunkUpdate.added)\n const updateDeleted = new Set(mergedChunkUpdate.deleted)\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId])\n }\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId)\n }\n chunksAdded.set(chunkPath, updateAdded)\n chunksDeleted.set(chunkPath, updateDeleted)\n break\n }\n default:\n invariant(\n mergedChunkUpdate,\n (mergedChunkUpdate) =>\n `Unknown merged chunk update type: ${mergedChunkUpdate.type}`\n )\n }\n }\n\n // If a module was added from one chunk and deleted from another in the same update,\n // consider it to be modified, as it means the module was moved from one chunk to another\n // AND has new code in a single update.\n for (const moduleId of added.keys()) {\n if (deleted.has(moduleId)) {\n added.delete(moduleId)\n deleted.delete(moduleId)\n }\n }\n\n for (const [moduleId, entry] of Object.entries(entries)) {\n // Modules that haven't been added to any chunk but have new code are considered\n // to be modified.\n // This needs to be under the previous loop, as we need it to get rid of modules\n // that were added and deleted in the same update.\n if (!added.has(moduleId)) {\n modified.set(moduleId, entry)\n }\n }\n\n return { added, deleted, modified, chunksAdded, chunksDeleted }\n}\n\ntype ModuleEffect =\n | {\n type: 'unaccepted'\n dependencyChain: ModuleId[]\n }\n | {\n type: 'self-declined'\n dependencyChain: ModuleId[]\n moduleId: ModuleId\n }\n | {\n type: 'accepted'\n moduleId: ModuleId\n outdatedModules: Set\n }\n\nfunction getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect {\n const outdatedModules: Set = new Set()\n\n type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] }\n\n const queue: QueueItem[] = [\n {\n moduleId,\n dependencyChain: [],\n },\n ]\n\n let nextItem\n while ((nextItem = queue.shift())) {\n const { moduleId, dependencyChain } = nextItem\n\n if (moduleId != null) {\n if (outdatedModules.has(moduleId)) {\n // Avoid infinite loops caused by cycles between modules in the dependency chain.\n continue\n }\n\n outdatedModules.add(moduleId)\n }\n\n // We've arrived at the runtime of the chunk, which means that nothing\n // else above can accept this update.\n if (moduleId === undefined) {\n return {\n type: 'unaccepted',\n dependencyChain,\n }\n }\n\n const module = devModuleCache[moduleId]\n const hotState = moduleHotState.get(module)!\n\n if (\n // The module is not in the cache. Since this is a \"modified\" update,\n // it means that the module was never instantiated before.\n !module || // The module accepted itself without invalidating globalThis.\n // TODO is that right?\n (hotState.selfAccepted && !hotState.selfInvalidated)\n ) {\n continue\n }\n\n if (hotState.selfDeclined) {\n return {\n type: 'self-declined',\n dependencyChain,\n moduleId,\n }\n }\n\n if (runtimeModules.has(moduleId)) {\n queue.push({\n moduleId: undefined,\n dependencyChain: [...dependencyChain, moduleId],\n })\n continue\n }\n\n for (const parentId of module.parents) {\n const parent = devModuleCache[parentId]\n\n if (!parent) {\n // TODO(alexkirsz) Is this even possible?\n continue\n }\n\n // TODO(alexkirsz) Dependencies: check accepted and declined\n // dependencies here.\n\n queue.push({\n moduleId: parentId,\n dependencyChain: [...dependencyChain, moduleId],\n })\n }\n }\n\n return {\n type: 'accepted',\n moduleId,\n outdatedModules,\n }\n}\n\nfunction handleApply(chunkListPath: ChunkListPath, update: ServerMessage) {\n switch (update.type) {\n case 'partial': {\n // This indicates that the update is can be applied to the current state of the application.\n applyUpdate(update.instruction)\n break\n }\n case 'restart': {\n // This indicates that there is no way to apply the update to the\n // current state of the application, and that the application must be\n // restarted.\n DEV_BACKEND.restart()\n break\n }\n case 'notFound': {\n // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed,\n // or the page itself was deleted.\n // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to.\n // If it is a runtime chunk list, we restart the application.\n if (runtimeChunkLists.has(chunkListPath)) {\n DEV_BACKEND.restart()\n } else {\n disposeChunkList(chunkListPath)\n }\n break\n }\n default:\n throw new Error(`Unknown update type: ${update.type}`)\n }\n}\n\nfunction createModuleHot(\n moduleId: ModuleId,\n hotData: HotData\n): { hot: Hot; hotState: HotState } {\n const hotState: HotState = {\n selfAccepted: false,\n selfDeclined: false,\n selfInvalidated: false,\n disposeHandlers: [],\n }\n\n const hot: Hot = {\n // TODO(alexkirsz) This is not defined in the HMR API. It was used to\n // decide whether to warn whenever an HMR-disposed module required other\n // modules. We might want to remove it.\n active: true,\n\n data: hotData ?? {},\n\n // TODO(alexkirsz) Support full (dep, callback, errorHandler) form.\n accept: (\n modules?: string | string[] | AcceptErrorHandler,\n _callback?: AcceptCallback,\n _errorHandler?: AcceptErrorHandler\n ) => {\n if (modules === undefined) {\n hotState.selfAccepted = true\n } else if (typeof modules === 'function') {\n hotState.selfAccepted = modules\n } else {\n throw new Error('unsupported `accept` signature')\n }\n },\n\n decline: (dep) => {\n if (dep === undefined) {\n hotState.selfDeclined = true\n } else {\n throw new Error('unsupported `decline` signature')\n }\n },\n\n dispose: (callback) => {\n hotState.disposeHandlers.push(callback)\n },\n\n addDisposeHandler: (callback) => {\n hotState.disposeHandlers.push(callback)\n },\n\n removeDisposeHandler: (callback) => {\n const idx = hotState.disposeHandlers.indexOf(callback)\n if (idx >= 0) {\n hotState.disposeHandlers.splice(idx, 1)\n }\n },\n\n invalidate: () => {\n hotState.selfInvalidated = true\n queuedInvalidatedModules.add(moduleId)\n },\n\n // NOTE(alexkirsz) This is part of the management API, which we don't\n // implement, but the Next.js React Refresh runtime uses this to decide\n // whether to schedule an update.\n status: () => 'idle',\n\n // NOTE(alexkirsz) Since we always return \"idle\" for now, these are no-ops.\n addStatusHandler: (_handler) => {},\n removeStatusHandler: (_handler) => {},\n\n // NOTE(jridgewell) Check returns the list of updated modules, but we don't\n // want the webpack code paths to ever update (the turbopack paths handle\n // this already).\n check: () => Promise.resolve(null),\n }\n\n return { hot, hotState }\n}\n\n/**\n * Removes a module from a chunk.\n * Returns `true` if there are no remaining chunks including this module.\n */\nfunction removeModuleFromChunk(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): boolean {\n const moduleChunks = moduleChunksMap.get(moduleId)!\n moduleChunks.delete(chunkPath)\n\n const chunkModules = chunkModulesMap.get(chunkPath)!\n chunkModules.delete(moduleId)\n\n const noRemainingModules = chunkModules.size === 0\n if (noRemainingModules) {\n chunkModulesMap.delete(chunkPath)\n }\n\n const noRemainingChunks = moduleChunks.size === 0\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId)\n }\n\n return noRemainingChunks\n}\n\n/**\n * Disposes of a chunk list and its corresponding exclusive chunks.\n */\nfunction disposeChunkList(chunkListPath: ChunkListPath): boolean {\n const chunkPaths = chunkListChunksMap.get(chunkListPath)\n if (chunkPaths == null) {\n return false\n }\n chunkListChunksMap.delete(chunkListPath)\n\n for (const chunkPath of chunkPaths) {\n const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!\n chunkChunkLists.delete(chunkListPath)\n\n if (chunkChunkLists.size === 0) {\n chunkChunkListsMap.delete(chunkPath)\n disposeChunk(chunkPath)\n }\n }\n\n // We must also dispose of the chunk list's chunk itself to ensure it may\n // be reloaded properly in the future.\n const chunkListUrl = getChunkRelativeUrl(chunkListPath)\n\n DEV_BACKEND.unloadChunk?.(chunkListUrl)\n\n return true\n}\n\n/**\n * Disposes of a chunk and its corresponding exclusive modules.\n *\n * @returns Whether the chunk was disposed of.\n */\nfunction disposeChunk(chunkPath: ChunkPath): boolean {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n // This should happen whether the chunk has any modules in it or not.\n // For instance, CSS chunks have no modules in them, but they still need to be unloaded.\n DEV_BACKEND.unloadChunk?.(chunkUrl)\n\n const chunkModules = chunkModulesMap.get(chunkPath)\n if (chunkModules == null) {\n return false\n }\n chunkModules.delete(chunkPath)\n\n for (const moduleId of chunkModules) {\n const moduleChunks = moduleChunksMap.get(moduleId)!\n moduleChunks.delete(chunkPath)\n\n const noRemainingChunks = moduleChunks.size === 0\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId)\n disposeModule(moduleId, 'clear')\n availableModules.delete(moduleId)\n }\n }\n\n return true\n}\n\n/**\n * Subscribes to chunk list updates from the update server and applies them.\n */\nfunction registerChunkList(chunkList: ChunkList) {\n const chunkListScript = chunkList.script\n const chunkListPath = getPathFromScript(chunkListScript)\n // The \"chunk\" is also registered to finish the loading in the backend\n BACKEND.registerChunk(chunkListPath as string as ChunkPath)\n globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!.push([\n chunkListPath,\n handleApply.bind(null, chunkListPath),\n ])\n\n // Adding chunks to chunk lists and vice versa.\n const chunkPaths = new Set(chunkList.chunks.map(getChunkPath))\n chunkListChunksMap.set(chunkListPath, chunkPaths)\n for (const chunkPath of chunkPaths) {\n let chunkChunkLists = chunkChunkListsMap.get(chunkPath)\n if (!chunkChunkLists) {\n chunkChunkLists = new Set([chunkListPath])\n chunkChunkListsMap.set(chunkPath, chunkChunkLists)\n } else {\n chunkChunkLists.add(chunkListPath)\n }\n }\n\n if (chunkList.source === 'entry') {\n markChunkListAsRuntime(chunkListPath)\n }\n}\n\nglobalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= []\n"],"names":[],"mappings":"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","ignoreList":[0]}}, - {"offset": {"line": 1430, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/dom/runtime-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n\ntype ChunkResolver = {\n resolved: boolean\n loadingStarted: boolean\n resolve: () => void\n reject: (error?: Error) => void\n promise: Promise\n}\n\nlet BACKEND: RuntimeBackend\n\nfunction augmentContext(context: unknown): unknown {\n return context\n}\n\nfunction fetchWebAssembly(wasmChunkPath: ChunkPath) {\n return fetch(getChunkRelativeUrl(wasmChunkPath))\n}\n\nasync function loadWebAssembly(\n _source: unknown,\n wasmChunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module,\n importsObj: WebAssembly.Imports\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath)\n\n const { instance } = await WebAssembly.instantiateStreaming(req, importsObj)\n\n return instance.exports\n}\n\nasync function loadWebAssemblyModule(\n _source: unknown,\n wasmChunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath)\n\n return await WebAssembly.compileStreaming(req)\n}\n\n/**\n * Maps chunk paths to the corresponding resolver.\n */\nconst chunkResolvers: Map = new Map()\n\n;(() => {\n BACKEND = {\n async registerChunk(chunkPath, params) {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n\n const resolver = getOrCreateResolver(chunkUrl)\n resolver.resolve()\n\n if (params == null) {\n return\n }\n\n for (const otherChunkData of params.otherChunks) {\n const otherChunkPath = getChunkPath(otherChunkData)\n const otherChunkUrl = getChunkRelativeUrl(otherChunkPath)\n\n // Chunk might have started loading, so we want to avoid triggering another load.\n getOrCreateResolver(otherChunkUrl)\n }\n\n // This waits for chunks to be loaded, but also marks included items as available.\n await Promise.all(\n params.otherChunks.map((otherChunkData) =>\n loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData)\n )\n )\n\n if (params.runtimeModuleIds.length > 0) {\n for (const moduleId of params.runtimeModuleIds) {\n getOrInstantiateRuntimeModule(moduleId, chunkPath)\n }\n }\n },\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n loadChunk(chunkUrl, source) {\n return doLoadChunk(chunkUrl, source)\n },\n }\n\n function getOrCreateResolver(chunkUrl: ChunkUrl): ChunkResolver {\n let resolver = chunkResolvers.get(chunkUrl)\n if (!resolver) {\n let resolve: () => void\n let reject: (error?: Error) => void\n const promise = new Promise((innerResolve, innerReject) => {\n resolve = innerResolve\n reject = innerReject\n })\n resolver = {\n resolved: false,\n loadingStarted: false,\n promise,\n resolve: () => {\n resolver!.resolved = true\n resolve()\n },\n reject: reject!,\n }\n chunkResolvers.set(chunkUrl, resolver)\n }\n return resolver\n }\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n function doLoadChunk(chunkUrl: ChunkUrl, source: SourceInfo) {\n const resolver = getOrCreateResolver(chunkUrl)\n if (resolver.loadingStarted) {\n return resolver.promise\n }\n\n if (source.type === SourceType.Runtime) {\n // We don't need to load chunks references from runtime code, as they're already\n // present in the DOM.\n resolver.loadingStarted = true\n\n if (isCss(chunkUrl)) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n }\n\n // We need to wait for JS chunks to register themselves within `registerChunk`\n // before we can start instantiating runtime modules, hence the absence of\n // `resolver.resolve()` in this branch.\n\n return resolver.promise\n }\n\n if (typeof importScripts === 'function') {\n // We're in a web worker\n if (isCss(chunkUrl)) {\n // ignore\n } else if (isJs(chunkUrl)) {\n self.TURBOPACK_NEXT_CHUNK_URLS!.push(chunkUrl)\n importScripts(TURBOPACK_WORKER_LOCATION + chunkUrl)\n } else {\n throw new Error(\n `can't infer type of chunk from URL ${chunkUrl} in worker`\n )\n }\n } else {\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl)\n\n if (isCss(chunkUrl)) {\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n )\n if (previousLinks.length > 0) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n } else {\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = chunkUrl\n link.onerror = () => {\n resolver.reject()\n }\n link.onload = () => {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n }\n document.body.appendChild(link)\n }\n } else if (isJs(chunkUrl)) {\n const previousScripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n )\n if (previousScripts.length > 0) {\n // There is this edge where the script already failed loading, but we\n // can't detect that. The Promise will never resolve in this case.\n for (const script of Array.from(previousScripts)) {\n script.addEventListener('error', () => {\n resolver.reject()\n })\n }\n } else {\n const script = document.createElement('script')\n script.src = chunkUrl\n // We'll only mark the chunk as loaded once the script has been executed,\n // which happens in `registerChunk`. Hence the absence of `resolve()` in\n // this branch.\n script.onerror = () => {\n resolver.reject()\n }\n document.body.appendChild(script)\n }\n } else {\n throw new Error(`can't infer type of chunk from URL ${chunkUrl}`)\n }\n }\n\n resolver.loadingStarted = true\n return resolver.promise\n }\n})()\n"],"names":[],"mappings":"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","ignoreList":[0]}}, - {"offset": {"line": 1596, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/dom/dev-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n/// \n/// \n\nlet DEV_BACKEND: DevRuntimeBackend\n;(() => {\n DEV_BACKEND = {\n unloadChunk(chunkUrl) {\n deleteResolver(chunkUrl)\n\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl)\n\n if (isCss(chunkUrl)) {\n const links = document.querySelectorAll(\n `link[href=\"${chunkUrl}\"],link[href^=\"${chunkUrl}?\"],link[href=\"${decodedChunkUrl}\"],link[href^=\"${decodedChunkUrl}?\"]`\n )\n for (const link of Array.from(links)) {\n link.remove()\n }\n } else if (isJs(chunkUrl)) {\n // Unloading a JS chunk would have no effect, as it lives in the JS\n // runtime once evaluated.\n // However, we still want to remove the script tag from the DOM to keep\n // the HTML somewhat consistent from the user's perspective.\n const scripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n )\n for (const script of Array.from(scripts)) {\n script.remove()\n }\n } else {\n throw new Error(`can't infer type of chunk from URL ${chunkUrl}`)\n }\n },\n\n reloadChunk(chunkUrl) {\n return new Promise((resolve, reject) => {\n if (!isCss(chunkUrl)) {\n reject(new Error('The DOM backend can only reload CSS chunks'))\n return\n }\n\n const decodedChunkUrl = decodeURI(chunkUrl)\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n )\n\n if (previousLinks.length === 0) {\n reject(new Error(`No link element found for chunk ${chunkUrl}`))\n return\n }\n\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n\n if (navigator.userAgent.includes('Firefox')) {\n // Firefox won't reload CSS files that were previously loaded on the current page,\n // we need to add a query param to make sure CSS is actually reloaded from the server.\n //\n // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506\n //\n // Safari has a similar issue, but only if you have a `` tag\n // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726\n link.href = `${chunkUrl}?ts=${Date.now()}`\n } else {\n link.href = chunkUrl\n }\n\n link.onerror = () => {\n reject()\n }\n link.onload = () => {\n // First load the new CSS, then remove the old ones. This prevents visible\n // flickering that would happen in-between removing the previous CSS and\n // loading the new one.\n for (const previousLink of Array.from(previousLinks))\n previousLink.remove()\n\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolve()\n }\n\n // Make sure to insert the new CSS right after the previous one, so that\n // its precedence is higher.\n previousLinks[0].parentElement!.insertBefore(\n link,\n previousLinks[0].nextSibling\n )\n })\n },\n\n restart: () => self.location.reload(),\n }\n\n function deleteResolver(chunkUrl: ChunkUrl) {\n chunkResolvers.delete(chunkUrl)\n }\n})()\n\nfunction _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory {\n code += `\\n\\n//# sourceURL=${encodeURI(\n location.origin + CHUNK_BASE_PATH + url + CHUNK_SUFFIX_PATH\n )}`\n if (map) {\n code += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(\n // btoa doesn't handle nonlatin characters, so escape them as \\x sequences\n // See https://stackoverflow.com/a/26603875\n unescape(encodeURIComponent(map))\n )}`\n }\n\n // eslint-disable-next-line no-eval\n return eval(code)\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,oDAAoD,GAEpD,gDAAgD;AAChD,4CAA4C;AAC5C,iDAAiD;AACjD,0DAA0D;AAE1D,IAAI;AACH,CAAC;IACA,cAAc;QACZ,aAAY,QAAQ;YAClB,eAAe;YAEf,gFAAgF;YAChF,MAAM,kBAAkB,UAAU;YAElC,IAAI,MAAM,WAAW;gBACnB,MAAM,QAAQ,SAAS,gBAAgB,CACrC,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,SAAS,eAAe,EAAE,gBAAgB,eAAe,EAAE,gBAAgB,GAAG,CAAC;gBAEzH,KAAK,MAAM,QAAQ,MAAM,IAAI,CAAC,OAAQ;oBACpC,KAAK,MAAM;gBACb;YACF,OAAO,IAAI,KAAK,WAAW;gBACzB,mEAAmE;gBACnE,0BAA0B;gBAC1B,uEAAuE;gBACvE,4DAA4D;gBAC5D,MAAM,UAAU,SAAS,gBAAgB,CACvC,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB,EAAE,gBAAgB,gBAAgB,EAAE,gBAAgB,GAAG,CAAC;gBAE7H,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,SAAU;oBACxC,OAAO,MAAM;gBACf;YACF,OAAO;gBACL,MAAM,IAAI,MAAM,CAAC,mCAAmC,EAAE,UAAU;YAClE;QACF;QAEA,aAAY,QAAQ;YAClB,OAAO,IAAI,QAAc,CAAC,SAAS;gBACjC,IAAI,CAAC,MAAM,WAAW;oBACpB,OAAO,IAAI,MAAM;oBACjB;gBACF;gBAEA,MAAM,kBAAkB,UAAU;gBAClC,MAAM,gBAAgB,SAAS,gBAAgB,CAC7C,CAAC,2BAA2B,EAAE,SAAS,+BAA+B,EAAE,SAAS,+BAA+B,EAAE,gBAAgB,+BAA+B,EAAE,gBAAgB,GAAG,CAAC;gBAGzL,IAAI,cAAc,MAAM,KAAK,GAAG;oBAC9B,OAAO,IAAI,MAAM,CAAC,gCAAgC,EAAE,UAAU;oBAC9D;gBACF;gBAEA,MAAM,OAAO,SAAS,aAAa,CAAC;gBACpC,KAAK,GAAG,GAAG;gBAEX,IAAI,UAAU,SAAS,CAAC,QAAQ,CAAC,YAAY;oBAC3C,kFAAkF;oBAClF,sFAAsF;oBACtF,EAAE;oBACF,qFAAqF;oBACrF,EAAE;oBACF,oFAAoF;oBACpF,6FAA6F;oBAC7F,KAAK,IAAI,GAAG,GAAG,SAAS,IAAI,EAAE,KAAK,GAAG,IAAI;gBAC5C,OAAO;oBACL,KAAK,IAAI,GAAG;gBACd;gBAEA,KAAK,OAAO,GAAG;oBACb;gBACF;gBACA,KAAK,MAAM,GAAG;oBACZ,0EAA0E;oBAC1E,wEAAwE;oBACxE,uBAAuB;oBACvB,KAAK,MAAM,gBAAgB,MAAM,IAAI,CAAC,eACpC,aAAa,MAAM;oBAErB,uEAAuE;oBACvE,oBAAoB;oBACpB;gBACF;gBAEA,wEAAwE;gBACxE,4BAA4B;gBAC5B,aAAa,CAAC,EAAE,CAAC,aAAa,CAAE,YAAY,CAC1C,MACA,aAAa,CAAC,EAAE,CAAC,WAAW;YAEhC;QACF;QAEA,SAAS,IAAM,KAAK,QAAQ,CAAC,MAAM;IACrC;IAEA,SAAS,eAAe,QAAkB;QACxC,eAAe,MAAM,CAAC;IACxB;AACF,CAAC;AAED,SAAS,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAyB;IACtD,QAAQ,CAAC,kBAAkB,EAAE,UAC3B,SAAS,MAAM,GAAG,kBAAkB,MAAM,oBACzC;IACH,IAAI,KAAK;QACP,QAAQ,CAAC,kEAAkE,EAAE,KAC3E,0EAA0E;QAC1E,2CAA2C;QAC3C,SAAS,mBAAmB,QAC3B;IACL;IAEA,mCAAmC;IACnC,OAAO,KAAK;AACd","ignoreList":[0]}}] + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n\ntype EsmNamespaceObject = Record\n\n// @ts-ignore Defined in `dev-base.ts`\ndeclare function getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: M\n): M\n\nconst REEXPORTED_OBJECTS = Symbol('reexported objects')\n\ntype ModuleContextMap = Record\n\ninterface ModuleContextEntry {\n id: () => ModuleId\n module: () => any\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject\n\n // async import call\n import(moduleId: ModuleId): Promise\n\n keys(): ModuleId[]\n\n resolve(moduleId: ModuleId): ModuleId\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: M\n) => M\n\ndeclare function getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\nconst toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options)\n}\n\nfunction getOverwrittenModule(\n moduleCache: ModuleCache,\n id: ModuleId\n): Module {\n let module = moduleCache[id]\n if (!module) {\n // This is invoked when a module is merged into another module, thus it wasn't invoced via\n // instantiateModule and the cache entry wasn't created yet.\n module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n namespaceObject: undefined,\n }\n moduleCache[id] = module\n }\n return module\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, '__esModule', { value: true })\n if (toStringTag) defineProp(exports, toStringTag, { value: 'Module' })\n for (const key in getters) {\n const item = getters[key]\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n })\n } else {\n defineProp(exports, key, { get: item, enumerable: true })\n }\n }\n Object.seal(exports)\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n moduleCache: ModuleCache,\n getters: Record any>,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n exports = module.exports\n }\n module.namespaceObject = module.exports\n esm(exports, getters)\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS]\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = []\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === 'default' ||\n prop === '__esModule'\n ) {\n return Reflect.get(target, prop)\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop)\n if (value !== undefined) return value\n }\n return undefined\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target)\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== 'default' && !keys.includes(key)) keys.push(key)\n }\n }\n return keys\n },\n })\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n moduleCache: ModuleCache,\n object: Record,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n exports = module.exports\n }\n ensureDynamicExports(module, exports)\n\n if (typeof object === 'object' && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object)\n }\n}\n\nfunction exportValue(\n module: Module,\n moduleCache: ModuleCache,\n value: any,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n }\n module.exports = value\n}\n\nfunction exportNamespace(\n module: Module,\n moduleCache: ModuleCache,\n namespace: any,\n id: ModuleId | undefined\n) {\n if (id != null) {\n module = getOverwrittenModule(moduleCache, id)\n }\n module.exports = module.namespaceObject = namespace\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key]\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)]\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null)\n for (\n let current = raw;\n (typeof current === 'object' || typeof current === 'function') &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key)\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && 'default' in getters)) {\n getters['default'] = () => raw\n }\n\n esm(ns, getters)\n return ns\n}\n\nfunction createNS(raw: Module['exports']): EsmNamespaceObject {\n if (typeof raw === 'function') {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args)\n }\n } else {\n return Object.create(null)\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ))\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n // @ts-ignore\n typeof require === 'function'\n ? // @ts-ignore\n require\n : function require() {\n throw new Error('Unexpected use of runtime require')\n }\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule)\n if (module.error) throw module.error\n return module.exports\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map)\n }\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id()\n }\n\n const e = new Error(`Cannot find module '${id}'`)\n ;(e as any).code = 'MODULE_NOT_FOUND'\n throw e\n }\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise)\n }\n\n return moduleContext\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === 'string' ? chunkData : chunkData.path\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === 'object' &&\n 'then' in maybePromise &&\n typeof maybePromise.then === 'function'\n )\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void\n let reject: (reason?: any) => void\n\n const promise = new Promise((res, rej) => {\n reject = rej\n resolve = res\n })\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n }\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol('turbopack queues')\nconst turbopackExports = Symbol('turbopack exports')\nconst turbopackError = Symbol('turbopack error')\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number }\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus\n}\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved\n queue.forEach((fn) => fn.queueCount--)\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()))\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void\n [turbopackExports]: Exports\n [turbopackError]?: any\n}\n\ntype AsyncModulePromise = Promise & AsyncModuleExt\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === 'object') {\n if (isAsyncModuleExt(dep)) return dep\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n })\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n }\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res\n resolveQueue(queue)\n },\n (err) => {\n obj[turbopackError] = err\n resolveQueue(queue)\n }\n )\n\n return obj\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n }\n })\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined\n\n const depQueues: Set = new Set()\n\n const { resolve, reject, promise: rawPromise } = createPromise()\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue)\n depQueues.forEach(fn)\n promise['catch'](() => {})\n },\n } satisfies AsyncModuleExt)\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v\n }\n },\n }\n\n Object.defineProperty(module, 'exports', attributes)\n Object.defineProperty(module, 'namespaceObject', attributes)\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps)\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError]\n return d[turbopackExports]\n })\n\n const { promise, resolve } = createPromise<() => Exports[]>()\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n })\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q)\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++\n q.push(fn)\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue))\n\n return fn.queueCount ? promise : getResult()\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err))\n } else {\n resolve(promise[turbopackExports])\n }\n\n resolveQueue(queue)\n }\n\n body(handleAsyncDependencies, asyncResult)\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, 'x:/')\n const values: Record = {}\n for (const key in realUrl) values[key] = (realUrl as any)[key]\n values.href = inputUrl\n values.pathname = inputUrl.replace(/[?#].*/, '')\n values.origin = values.protocol = ''\n values.toString = values.toJSON = (..._args: Array) => inputUrl\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n })\n}\n\nrelativeURL.prototype = URL.prototype\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`)\n}\n\n/**\n * A stub function to make `require` available but non-functional in ESM.\n */\nfunction requireStub(_moduleId: ModuleId): never {\n throw new Error('dynamic usage of require is not supported')\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}, + {"offset": {"line": 378, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/base/runtime-base.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n\n// Used in WebWorkers to tell the runtime about the chunk base path\ndeclare var TURBOPACK_WORKER_LOCATION: string\n// Used in WebWorkers to tell the runtime about the current chunk url since it can't be detected via document.currentScript\n// Note it's stored in reversed order to use push and pop\ndeclare var TURBOPACK_NEXT_CHUNK_URLS: ChunkUrl[] | undefined\n\n// Injected by rust code\ndeclare var CHUNK_BASE_PATH: string\ndeclare var CHUNK_SUFFIX_PATH: string\n\n// Provided by build or dev base\ndeclare function instantiateModule(id: ModuleId, source: SourceInfo): Module\n\ntype RuntimeParams = {\n otherChunks: ChunkData[]\n runtimeModuleIds: ModuleId[]\n}\n\ntype ChunkRegistration = [\n chunkPath: ChunkScript,\n chunkModules: CompressedModuleFactories,\n params: RuntimeParams | undefined,\n]\n\ntype ChunkList = {\n script: ChunkListScript\n chunks: ChunkData[]\n source: 'entry' | 'dynamic'\n}\n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n /**\n * The module was instantiated because it was included in a chunk's hot module\n * update.\n */\n Update = 2,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime\n chunkPath: ChunkPath\n }\n | {\n type: SourceType.Parent\n parentId: ModuleId\n }\n | {\n type: SourceType.Update\n parents?: ModuleId[]\n }\n\ninterface RuntimeBackend {\n registerChunk: (chunkPath: ChunkPath, params?: RuntimeParams) => void\n loadChunk: (chunkUrl: ChunkUrl, source: SourceInfo) => Promise\n}\n\ninterface DevRuntimeBackend {\n reloadChunk?: (chunkUrl: ChunkUrl) => Promise\n unloadChunk?: (chunkUrl: ChunkUrl) => void\n restart: () => void\n}\n\nconst moduleFactories: ModuleFactories = Object.create(null)\n/**\n * Module IDs that are instantiated as part of the runtime of a chunk.\n */\nconst runtimeModules: Set = new Set()\n/**\n * Map from module ID to the chunks that contain this module.\n *\n * In HMR, we need to keep track of which modules are contained in which so\n * chunks. This is so we don't eagerly dispose of a module when it is removed\n * from chunk A, but still exists in chunk B.\n */\nconst moduleChunksMap: Map> = new Map()\n/**\n * Map from a chunk path to all modules it contains.\n */\nconst chunkModulesMap: Map> = new Map()\n/**\n * Chunk lists that contain a runtime. When these chunk lists receive an update\n * that can't be reconciled with the current state of the page, we need to\n * reload the runtime entirely.\n */\nconst runtimeChunkLists: Set = new Set()\n/**\n * Map from a chunk list to the chunk paths it contains.\n */\nconst chunkListChunksMap: Map> = new Map()\n/**\n * Map from a chunk path to the chunk lists it belongs to.\n */\nconst chunkChunkListsMap: Map> = new Map()\n\nconst availableModules: Map | true> = new Map()\n\nconst availableModuleChunks: Map | true> = new Map()\n\nasync function loadChunk(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n if (typeof chunkData === 'string') {\n return loadChunkPath(source, chunkData)\n }\n\n const includedList = chunkData.included || []\n const modulesPromises = includedList.map((included) => {\n if (moduleFactories[included]) return true\n return availableModules.get(included)\n })\n if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) {\n // When all included items are already loaded or loading, we can skip loading ourselves\n return Promise.all(modulesPromises)\n }\n\n const includedModuleChunksList = chunkData.moduleChunks || []\n const moduleChunksPromises = includedModuleChunksList\n .map((included) => {\n // TODO(alexkirsz) Do we need this check?\n // if (moduleFactories[included]) return true;\n return availableModuleChunks.get(included)\n })\n .filter((p) => p)\n\n let promise\n if (moduleChunksPromises.length > 0) {\n // Some module chunks are already loaded or loading.\n\n if (moduleChunksPromises.length === includedModuleChunksList.length) {\n // When all included module chunks are already loaded or loading, we can skip loading ourselves\n return Promise.all(moduleChunksPromises)\n }\n\n const moduleChunksToLoad: Set = new Set()\n for (const moduleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(moduleChunk)) {\n moduleChunksToLoad.add(moduleChunk)\n }\n }\n\n for (const moduleChunkToLoad of moduleChunksToLoad) {\n const promise = loadChunkPath(source, moduleChunkToLoad)\n\n availableModuleChunks.set(moduleChunkToLoad, promise)\n\n moduleChunksPromises.push(promise)\n }\n\n promise = Promise.all(moduleChunksPromises)\n } else {\n promise = loadChunkPath(source, chunkData.path)\n\n // Mark all included module chunks as loading if they are not already loaded or loading.\n for (const includedModuleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(includedModuleChunk)) {\n availableModuleChunks.set(includedModuleChunk, promise)\n }\n }\n }\n\n for (const included of includedList) {\n if (!availableModules.has(included)) {\n // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier.\n // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway.\n availableModules.set(included, promise)\n }\n }\n\n return promise\n}\n\nasync function loadChunkByUrl(source: SourceInfo, chunkUrl: ChunkUrl) {\n try {\n await BACKEND.loadChunk(chunkUrl, source)\n } catch (error) {\n let loadReason\n switch (source.type) {\n case SourceType.Runtime:\n loadReason = `as a runtime dependency of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n loadReason = `from module ${source.parentId}`\n break\n case SourceType.Update:\n loadReason = 'from an HMR update'\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Failed to load chunk ${chunkUrl} ${loadReason}${\n error ? `: ${error}` : ''\n }`,\n error\n ? {\n cause: error,\n }\n : undefined\n )\n }\n}\n\nasync function loadChunkPath(\n source: SourceInfo,\n chunkPath: ChunkPath\n): Promise {\n const url = getChunkRelativeUrl(chunkPath)\n return loadChunkByUrl(source, url)\n}\n\n/**\n * Returns an absolute url to an asset.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId)\n return exported?.default ?? exported\n }\n}\n\n/**\n * no-op for browser\n * @param modulePath\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n return `/ROOT/${modulePath ?? ''}`\n}\n\n/**\n * Returns a blob URL for the worker.\n * @param chunks list of chunks to load\n */\nfunction getWorkerBlobURL(chunks: ChunkPath[]): string {\n // It is important to reverse the array so when bootstrapping we can infer what chunk is being\n // evaluated by poping urls off of this array. See `getPathFromScript`\n let bootstrap = `self.TURBOPACK_WORKER_LOCATION = ${JSON.stringify(location.origin)};\nself.TURBOPACK_NEXT_CHUNK_URLS = ${JSON.stringify(chunks.reverse().map(getChunkRelativeUrl), null, 2)};\nimportScripts(...self.TURBOPACK_NEXT_CHUNK_URLS.map(c => self.TURBOPACK_WORKER_LOCATION + c).reverse());`\n let blob = new Blob([bootstrap], { type: 'text/javascript' })\n return URL.createObjectURL(blob)\n}\n\n/**\n * Adds a module to a chunk.\n */\nfunction addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) {\n let moduleChunks = moduleChunksMap.get(moduleId)\n if (!moduleChunks) {\n moduleChunks = new Set([chunkPath])\n moduleChunksMap.set(moduleId, moduleChunks)\n } else {\n moduleChunks.add(chunkPath)\n }\n\n let chunkModules = chunkModulesMap.get(chunkPath)\n if (!chunkModules) {\n chunkModules = new Set([moduleId])\n chunkModulesMap.set(chunkPath, chunkModules)\n } else {\n chunkModules.add(moduleId)\n }\n}\n\n/**\n * Returns the first chunk that included a module.\n * This is used by the Node.js backend, hence why it's marked as unused in this\n * file.\n */\nfunction getFirstModuleChunk(moduleId: ModuleId) {\n const moduleChunkPaths = moduleChunksMap.get(moduleId)\n if (moduleChunkPaths == null) {\n return null\n }\n\n return moduleChunkPaths.values().next().value\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n/**\n * Returns the URL relative to the origin where a chunk can be fetched from.\n */\nfunction getChunkRelativeUrl(chunkPath: ChunkPath | ChunkListPath): ChunkUrl {\n return `${CHUNK_BASE_PATH}${chunkPath\n .split('/')\n .map((p) => encodeURIComponent(p))\n .join('/')}${CHUNK_SUFFIX_PATH}` as ChunkUrl\n}\n\n/**\n * Return the ChunkPath from a ChunkScript.\n */\nfunction getPathFromScript(chunkScript: ChunkPath | ChunkScript): ChunkPath\nfunction getPathFromScript(\n chunkScript: ChunkListPath | ChunkListScript\n): ChunkListPath\nfunction getPathFromScript(\n chunkScript: ChunkPath | ChunkListPath | ChunkScript | ChunkListScript\n): ChunkPath | ChunkListPath {\n if (typeof chunkScript === 'string') {\n return chunkScript as ChunkPath | ChunkListPath\n }\n const chunkUrl =\n typeof TURBOPACK_NEXT_CHUNK_URLS !== 'undefined'\n ? TURBOPACK_NEXT_CHUNK_URLS.pop()!\n : chunkScript.getAttribute('src')!\n const src = decodeURIComponent(chunkUrl.replace(/[?#].*$/, ''))\n const path = src.startsWith(CHUNK_BASE_PATH)\n ? src.slice(CHUNK_BASE_PATH.length)\n : src\n return path as ChunkPath | ChunkListPath\n}\n\n/**\n * Marks a chunk list as a runtime chunk list. There can be more than one\n * runtime chunk list. For instance, integration tests can have multiple chunk\n * groups loaded at runtime, each with its own chunk list.\n */\nfunction markChunkListAsRuntime(chunkListPath: ChunkListPath) {\n runtimeChunkLists.add(chunkListPath)\n}\n\nfunction registerChunk([\n chunkScript,\n chunkModules,\n runtimeParams,\n]: ChunkRegistration) {\n const chunkPath = getPathFromScript(chunkScript)\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n if (Array.isArray(moduleFactory)) {\n let [moduleFactoryFn, otherIds] = moduleFactory\n moduleFactories[moduleId] = moduleFactoryFn\n for (const otherModuleId of otherIds) {\n moduleFactories[otherModuleId] = moduleFactoryFn\n }\n } else {\n moduleFactories[moduleId] = moduleFactory\n }\n }\n addModuleToChunk(moduleId, chunkPath)\n }\n\n return BACKEND.registerChunk(chunkPath, runtimeParams)\n}\n\nconst regexJsUrl = /\\.js(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.\n */\nfunction isJs(chunkUrlOrPath: ChunkUrl | ChunkPath): boolean {\n return regexJsUrl.test(chunkUrlOrPath)\n}\n\nconst regexCssUrl = /\\.css(?:\\?[^#]*)?(?:#.*)?$/\n/**\n * Checks if a given path/URL ends with .css, optionally followed by ?query or #fragment.\n */\nfunction isCss(chunkUrl: ChunkUrl): boolean {\n return regexCssUrl.test(chunkUrl)\n}\n"],"names":[],"mappings":"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","ignoreList":[0]}}, + {"offset": {"line": 633, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/base/dev-base.ts"],"sourcesContent":["/// \n/// \n/// \n\n/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\nconst devModuleCache: ModuleCache = Object.create(null)\n\n// This file must not use `import` and `export` statements. Otherwise, it\n// becomes impossible to augment interfaces declared in ``d files\n// (e.g. `Module`). Hence, the need for `import()` here.\ntype RefreshRuntimeGlobals =\n import('@next/react-refresh-utils/dist/runtime').RefreshRuntimeGlobals\n\ndeclare var $RefreshHelpers$: RefreshRuntimeGlobals['$RefreshHelpers$']\ndeclare var $RefreshReg$: RefreshRuntimeGlobals['$RefreshReg$']\ndeclare var $RefreshSig$: RefreshRuntimeGlobals['$RefreshSig$']\ndeclare var $RefreshInterceptModuleExecution$: RefreshRuntimeGlobals['$RefreshInterceptModuleExecution$']\n\ntype RefreshContext = {\n register: RefreshRuntimeGlobals['$RefreshReg$']\n signature: RefreshRuntimeGlobals['$RefreshSig$']\n registerExports: typeof registerExportsAndSetupBoundaryForReactRefresh\n}\n\ntype RefreshHelpers = RefreshRuntimeGlobals['$RefreshHelpers$']\n\ninterface TurbopackDevBaseContext extends TurbopackBaseContext {\n k: RefreshContext\n R: ResolvePathFromModule\n}\n\ninterface TurbopackDevContext extends TurbopackDevBaseContext {}\n\ntype ModuleFactory = (\n this: Module['exports'],\n context: TurbopackDevBaseContext\n) => unknown\n\ninterface DevRuntimeBackend {\n reloadChunk?: (chunkUrl: ChunkUrl) => Promise\n unloadChunk?: (chunkUrl: ChunkUrl) => void\n restart: () => void\n}\n\nclass UpdateApplyError extends Error {\n name = 'UpdateApplyError'\n\n dependencyChain: string[]\n\n constructor(message: string, dependencyChain: string[]) {\n super(message)\n this.dependencyChain = dependencyChain\n }\n}\n\n/**\n * Maps module IDs to persisted data between executions of their hot module\n * implementation (`hot.data`).\n */\nconst moduleHotData: Map = new Map()\n/**\n * Maps module instances to their hot module state.\n */\nconst moduleHotState: Map = new Map()\n/**\n * Modules that call `module.hot.invalidate()` (while being updated).\n */\nconst queuedInvalidatedModules: Set = new Set()\n\n/**\n * Gets or instantiates a runtime module.\n */\n// @ts-ignore\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = devModuleCache[moduleId]\n if (module) {\n if (module.error) {\n throw module.error\n }\n return module\n }\n\n // @ts-ignore\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath })\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\n// @ts-ignore Defined in `runtime-utils.ts`\nconst getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent<\n HotModule\n> = (id, sourceModule) => {\n if (!sourceModule.hot.active) {\n console.warn(\n `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`\n )\n }\n\n const module = devModuleCache[id]\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id)\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id)\n }\n\n return module\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n })\n}\n\n// @ts-ignore Defined in `runtime-base.ts`\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id]\n if (typeof moduleFactory !== 'function') {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`\n break\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`\n break\n case SourceType.Update:\n instantiationReason = 'because of an HMR update'\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n )\n }\n\n const hotData = moduleHotData.get(id)!\n const { hot, hotState } = createModuleHot(id, hotData)\n\n let parents: ModuleId[]\n switch (source.type) {\n case SourceType.Runtime:\n runtimeModules.add(id)\n parents = []\n break\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId]\n break\n case SourceType.Update:\n parents = source.parents || []\n break\n default:\n invariant(source, (source) => `Unknown source type: ${source?.type}`)\n }\n\n const module: HotModule = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n hot,\n }\n\n devModuleCache[id] = module\n moduleHotState.set(module, hotState)\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id }\n\n runModuleExecutionHooks(module, (refresh) => {\n const r = commonJsRequire.bind(null, module)\n moduleFactory.call(\n module.exports,\n augmentContext({\n a: asyncModule.bind(null, module),\n e: module.exports,\n r: commonJsRequire.bind(null, module),\n t: runtimeRequire,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports, devModuleCache),\n j: dynamicExport.bind(null, module, module.exports, devModuleCache),\n v: exportValue.bind(null, module, devModuleCache),\n n: exportNamespace.bind(null, module, devModuleCache),\n m: module,\n c: devModuleCache,\n M: moduleFactories,\n l: loadChunk.bind(null, sourceInfo),\n L: loadChunkByUrl.bind(null, sourceInfo),\n w: loadWebAssembly.bind(null, sourceInfo),\n u: loadWebAssemblyModule.bind(null, sourceInfo),\n P: resolveAbsolutePath,\n U: relativeURL,\n k: refresh,\n R: createResolvePathFromModule(r),\n b: getWorkerBlobURL,\n z: requireStub,\n })\n )\n })\n } catch (error) {\n module.error = error as any\n throw error\n }\n\n module.loaded = true\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject)\n }\n\n return module\n}\n\n/**\n * NOTE(alexkirsz) Webpack has a \"module execution\" interception hook that\n * Next.js' React Refresh runtime hooks into to add module context to the\n * refresh registry.\n */\nfunction runModuleExecutionHooks(\n module: Module,\n executeModule: (ctx: RefreshContext) => void\n) {\n if (typeof globalThis.$RefreshInterceptModuleExecution$ === 'function') {\n const cleanupReactRefreshIntercept =\n globalThis.$RefreshInterceptModuleExecution$(module.id)\n try {\n executeModule({\n register: globalThis.$RefreshReg$,\n signature: globalThis.$RefreshSig$,\n registerExports: registerExportsAndSetupBoundaryForReactRefresh,\n })\n } finally {\n // Always cleanup the intercept, even if module execution failed.\n cleanupReactRefreshIntercept()\n }\n } else {\n // If the react refresh hooks are not installed we need to bind dummy functions.\n // This is expected when running in a Web Worker. It is also common in some of\n // our test environments.\n executeModule({\n register: (type, id) => {},\n signature: () => (type) => {},\n registerExports: (module, helpers) => {},\n })\n }\n}\n\n/**\n * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts\n */\nfunction registerExportsAndSetupBoundaryForReactRefresh(\n module: HotModule,\n helpers: RefreshHelpers\n) {\n const currentExports = module.exports\n const prevExports = module.hot.data.prevExports ?? null\n\n helpers.registerExportsForReactRefresh(currentExports, module.id)\n\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (helpers.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports on update, so we can compare the boundary\n // signatures.\n module.hot.dispose((data) => {\n data.prevExports = currentExports\n })\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n module.hot.accept()\n\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevExports !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (\n helpers.shouldInvalidateReactRefreshBoundary(\n helpers.getRefreshBoundarySignature(prevExports),\n helpers.getRefreshBoundarySignature(currentExports)\n )\n ) {\n module.hot.invalidate()\n } else {\n helpers.scheduleUpdate()\n }\n }\n } else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n const isNoLongerABoundary = prevExports !== null\n if (isNoLongerABoundary) {\n module.hot.invalidate()\n }\n }\n}\n\nfunction formatDependencyChain(dependencyChain: ModuleId[]): string {\n return `Dependency chain: ${dependencyChain.join(' -> ')}`\n}\n\nfunction computeOutdatedModules(\n added: Map,\n modified: Map\n): {\n outdatedModules: Set\n newModuleFactories: Map\n} {\n const newModuleFactories = new Map()\n\n for (const [moduleId, entry] of added) {\n if (entry != null) {\n newModuleFactories.set(moduleId, _eval(entry))\n }\n }\n\n const outdatedModules = computedInvalidatedModules(modified.keys())\n\n for (const [moduleId, entry] of modified) {\n newModuleFactories.set(moduleId, _eval(entry))\n }\n\n return { outdatedModules, newModuleFactories }\n}\n\nfunction computedInvalidatedModules(\n invalidated: Iterable\n): Set {\n const outdatedModules = new Set()\n\n for (const moduleId of invalidated) {\n const effect = getAffectedModuleEffects(moduleId)\n\n switch (effect.type) {\n case 'unaccepted':\n throw new UpdateApplyError(\n `cannot apply update: unaccepted module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n )\n case 'self-declined':\n throw new UpdateApplyError(\n `cannot apply update: self-declined module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n )\n case 'accepted':\n for (const outdatedModuleId of effect.outdatedModules) {\n outdatedModules.add(outdatedModuleId)\n }\n break\n // TODO(alexkirsz) Dependencies: handle dependencies effects.\n default:\n invariant(effect, (effect) => `Unknown effect type: ${effect?.type}`)\n }\n }\n\n return outdatedModules\n}\n\nfunction computeOutdatedSelfAcceptedModules(\n outdatedModules: Iterable\n): { moduleId: ModuleId; errorHandler: true | Function }[] {\n const outdatedSelfAcceptedModules: {\n moduleId: ModuleId\n errorHandler: true | Function\n }[] = []\n for (const moduleId of outdatedModules) {\n const module = devModuleCache[moduleId]\n const hotState = moduleHotState.get(module)!\n if (module && hotState.selfAccepted && !hotState.selfInvalidated) {\n outdatedSelfAcceptedModules.push({\n moduleId,\n errorHandler: hotState.selfAccepted,\n })\n }\n }\n return outdatedSelfAcceptedModules\n}\n\n/**\n * Adds, deletes, and moves modules between chunks. This must happen before the\n * dispose phase as it needs to know which modules were removed from all chunks,\n * which we can only compute *after* taking care of added and moved modules.\n */\nfunction updateChunksPhase(\n chunksAddedModules: Map>,\n chunksDeletedModules: Map>\n): { disposedModules: Set } {\n for (const [chunkPath, addedModuleIds] of chunksAddedModules) {\n for (const moduleId of addedModuleIds) {\n addModuleToChunk(moduleId, chunkPath)\n }\n }\n\n const disposedModules: Set = new Set()\n for (const [chunkPath, addedModuleIds] of chunksDeletedModules) {\n for (const moduleId of addedModuleIds) {\n if (removeModuleFromChunk(moduleId, chunkPath)) {\n disposedModules.add(moduleId)\n }\n }\n }\n\n return { disposedModules }\n}\n\nfunction disposePhase(\n outdatedModules: Iterable,\n disposedModules: Iterable\n): { outdatedModuleParents: Map> } {\n for (const moduleId of outdatedModules) {\n disposeModule(moduleId, 'replace')\n }\n\n for (const moduleId of disposedModules) {\n disposeModule(moduleId, 'clear')\n }\n\n // Removing modules from the module cache is a separate step.\n // We also want to keep track of previous parents of the outdated modules.\n const outdatedModuleParents = new Map()\n for (const moduleId of outdatedModules) {\n const oldModule = devModuleCache[moduleId]\n outdatedModuleParents.set(moduleId, oldModule?.parents)\n delete devModuleCache[moduleId]\n }\n\n // TODO(alexkirsz) Dependencies: remove outdated dependency from module\n // children.\n\n return { outdatedModuleParents }\n}\n\n/**\n * Disposes of an instance of a module.\n *\n * Returns the persistent hot data that should be kept for the next module\n * instance.\n *\n * NOTE: mode = \"replace\" will not remove modules from the devModuleCache\n * This must be done in a separate step afterwards.\n * This is important because all modules need to be disposed to update the\n * parent/child relationships before they are actually removed from the devModuleCache.\n * If this was done in this method, the following disposeModule calls won't find\n * the module from the module id in the cache.\n */\nfunction disposeModule(moduleId: ModuleId, mode: 'clear' | 'replace') {\n const module = devModuleCache[moduleId]\n if (!module) {\n return\n }\n\n const hotState = moduleHotState.get(module)!\n const data = {}\n\n // Run the `hot.dispose` handler, if any, passing in the persistent\n // `hot.data` object.\n for (const disposeHandler of hotState.disposeHandlers) {\n disposeHandler(data)\n }\n\n // This used to warn in `getOrInstantiateModuleFromParent` when a disposed\n // module is still importing other modules.\n module.hot.active = false\n\n moduleHotState.delete(module)\n\n // TODO(alexkirsz) Dependencies: delete the module from outdated deps.\n\n // Remove the disposed module from its children's parent list.\n // It will be added back once the module re-instantiates and imports its\n // children again.\n for (const childId of module.children) {\n const child = devModuleCache[childId]\n if (!child) {\n continue\n }\n\n const idx = child.parents.indexOf(module.id)\n if (idx >= 0) {\n child.parents.splice(idx, 1)\n }\n }\n\n switch (mode) {\n case 'clear':\n delete devModuleCache[module.id]\n moduleHotData.delete(module.id)\n break\n case 'replace':\n moduleHotData.set(module.id, data)\n break\n default:\n invariant(mode, (mode) => `invalid mode: ${mode}`)\n }\n}\n\nfunction applyPhase(\n outdatedSelfAcceptedModules: {\n moduleId: ModuleId\n errorHandler: true | Function\n }[],\n newModuleFactories: Map,\n outdatedModuleParents: Map>,\n reportError: (err: any) => void\n) {\n // Update module factories.\n for (const [moduleId, factory] of newModuleFactories.entries()) {\n moduleFactories[moduleId] = factory\n }\n\n // TODO(alexkirsz) Run new runtime entries here.\n\n // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps.\n\n // Re-instantiate all outdated self-accepted modules.\n for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) {\n try {\n instantiateModule(moduleId, {\n type: SourceType.Update,\n parents: outdatedModuleParents.get(moduleId),\n })\n } catch (err) {\n if (typeof errorHandler === 'function') {\n try {\n errorHandler(err, { moduleId, module: devModuleCache[moduleId] })\n } catch (err2) {\n reportError(err2)\n reportError(err)\n }\n } else {\n reportError(err)\n }\n }\n }\n}\n\nfunction applyUpdate(update: PartialUpdate) {\n switch (update.type) {\n case 'ChunkListUpdate':\n applyChunkListUpdate(update)\n break\n default:\n invariant(update, (update) => `Unknown update type: ${update.type}`)\n }\n}\n\nfunction applyChunkListUpdate(update: ChunkListUpdate) {\n if (update.merged != null) {\n for (const merged of update.merged) {\n switch (merged.type) {\n case 'EcmascriptMergedUpdate':\n applyEcmascriptMergedUpdate(merged)\n break\n default:\n invariant(merged, (merged) => `Unknown merged type: ${merged.type}`)\n }\n }\n }\n\n if (update.chunks != null) {\n for (const [chunkPath, chunkUpdate] of Object.entries(\n update.chunks\n ) as Array<[ChunkPath, ChunkUpdate]>) {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n\n switch (chunkUpdate.type) {\n case 'added':\n BACKEND.loadChunk(chunkUrl, { type: SourceType.Update })\n break\n case 'total':\n DEV_BACKEND.reloadChunk?.(chunkUrl)\n break\n case 'deleted':\n DEV_BACKEND.unloadChunk?.(chunkUrl)\n break\n case 'partial':\n invariant(\n chunkUpdate.instruction,\n (instruction) =>\n `Unknown partial instruction: ${JSON.stringify(instruction)}.`\n )\n break\n default:\n invariant(\n chunkUpdate,\n (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}`\n )\n }\n }\n }\n}\n\nfunction applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) {\n const { entries = {}, chunks = {} } = update\n const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(\n entries,\n chunks\n )\n const { outdatedModules, newModuleFactories } = computeOutdatedModules(\n added,\n modified\n )\n const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted)\n\n applyInternal(outdatedModules, disposedModules, newModuleFactories)\n}\n\nfunction applyInvalidatedModules(outdatedModules: Set) {\n if (queuedInvalidatedModules.size > 0) {\n computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => {\n outdatedModules.add(moduleId)\n })\n\n queuedInvalidatedModules.clear()\n }\n\n return outdatedModules\n}\n\nfunction applyInternal(\n outdatedModules: Set,\n disposedModules: Iterable,\n newModuleFactories: Map\n) {\n outdatedModules = applyInvalidatedModules(outdatedModules)\n\n const outdatedSelfAcceptedModules =\n computeOutdatedSelfAcceptedModules(outdatedModules)\n\n const { outdatedModuleParents } = disposePhase(\n outdatedModules,\n disposedModules\n )\n\n // we want to continue on error and only throw the error after we tried applying all updates\n let error: any\n\n function reportError(err: any) {\n if (!error) error = err\n }\n\n applyPhase(\n outdatedSelfAcceptedModules,\n newModuleFactories,\n outdatedModuleParents,\n reportError\n )\n\n if (error) {\n throw error\n }\n\n if (queuedInvalidatedModules.size > 0) {\n applyInternal(new Set(), [], new Map())\n }\n}\n\nfunction computeChangedModules(\n entries: Record,\n updates: Record\n): {\n added: Map\n modified: Map\n deleted: Set\n chunksAdded: Map>\n chunksDeleted: Map>\n} {\n const chunksAdded = new Map()\n const chunksDeleted = new Map()\n const added: Map = new Map()\n const modified = new Map()\n const deleted: Set = new Set()\n\n for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates) as Array<\n [ChunkPath, EcmascriptMergedChunkUpdate]\n >) {\n switch (mergedChunkUpdate.type) {\n case 'added': {\n const updateAdded = new Set(mergedChunkUpdate.modules)\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId])\n }\n chunksAdded.set(chunkPath, updateAdded)\n break\n }\n case 'deleted': {\n // We could also use `mergedChunkUpdate.modules` here.\n const updateDeleted = new Set(chunkModulesMap.get(chunkPath))\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId)\n }\n chunksDeleted.set(chunkPath, updateDeleted)\n break\n }\n case 'partial': {\n const updateAdded = new Set(mergedChunkUpdate.added)\n const updateDeleted = new Set(mergedChunkUpdate.deleted)\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId])\n }\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId)\n }\n chunksAdded.set(chunkPath, updateAdded)\n chunksDeleted.set(chunkPath, updateDeleted)\n break\n }\n default:\n invariant(\n mergedChunkUpdate,\n (mergedChunkUpdate) =>\n `Unknown merged chunk update type: ${mergedChunkUpdate.type}`\n )\n }\n }\n\n // If a module was added from one chunk and deleted from another in the same update,\n // consider it to be modified, as it means the module was moved from one chunk to another\n // AND has new code in a single update.\n for (const moduleId of added.keys()) {\n if (deleted.has(moduleId)) {\n added.delete(moduleId)\n deleted.delete(moduleId)\n }\n }\n\n for (const [moduleId, entry] of Object.entries(entries)) {\n // Modules that haven't been added to any chunk but have new code are considered\n // to be modified.\n // This needs to be under the previous loop, as we need it to get rid of modules\n // that were added and deleted in the same update.\n if (!added.has(moduleId)) {\n modified.set(moduleId, entry)\n }\n }\n\n return { added, deleted, modified, chunksAdded, chunksDeleted }\n}\n\ntype ModuleEffect =\n | {\n type: 'unaccepted'\n dependencyChain: ModuleId[]\n }\n | {\n type: 'self-declined'\n dependencyChain: ModuleId[]\n moduleId: ModuleId\n }\n | {\n type: 'accepted'\n moduleId: ModuleId\n outdatedModules: Set\n }\n\nfunction getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect {\n const outdatedModules: Set = new Set()\n\n type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] }\n\n const queue: QueueItem[] = [\n {\n moduleId,\n dependencyChain: [],\n },\n ]\n\n let nextItem\n while ((nextItem = queue.shift())) {\n const { moduleId, dependencyChain } = nextItem\n\n if (moduleId != null) {\n if (outdatedModules.has(moduleId)) {\n // Avoid infinite loops caused by cycles between modules in the dependency chain.\n continue\n }\n\n outdatedModules.add(moduleId)\n }\n\n // We've arrived at the runtime of the chunk, which means that nothing\n // else above can accept this update.\n if (moduleId === undefined) {\n return {\n type: 'unaccepted',\n dependencyChain,\n }\n }\n\n const module = devModuleCache[moduleId]\n const hotState = moduleHotState.get(module)!\n\n if (\n // The module is not in the cache. Since this is a \"modified\" update,\n // it means that the module was never instantiated before.\n !module || // The module accepted itself without invalidating globalThis.\n // TODO is that right?\n (hotState.selfAccepted && !hotState.selfInvalidated)\n ) {\n continue\n }\n\n if (hotState.selfDeclined) {\n return {\n type: 'self-declined',\n dependencyChain,\n moduleId,\n }\n }\n\n if (runtimeModules.has(moduleId)) {\n queue.push({\n moduleId: undefined,\n dependencyChain: [...dependencyChain, moduleId],\n })\n continue\n }\n\n for (const parentId of module.parents) {\n const parent = devModuleCache[parentId]\n\n if (!parent) {\n // TODO(alexkirsz) Is this even possible?\n continue\n }\n\n // TODO(alexkirsz) Dependencies: check accepted and declined\n // dependencies here.\n\n queue.push({\n moduleId: parentId,\n dependencyChain: [...dependencyChain, moduleId],\n })\n }\n }\n\n return {\n type: 'accepted',\n moduleId,\n outdatedModules,\n }\n}\n\nfunction handleApply(chunkListPath: ChunkListPath, update: ServerMessage) {\n switch (update.type) {\n case 'partial': {\n // This indicates that the update is can be applied to the current state of the application.\n applyUpdate(update.instruction)\n break\n }\n case 'restart': {\n // This indicates that there is no way to apply the update to the\n // current state of the application, and that the application must be\n // restarted.\n DEV_BACKEND.restart()\n break\n }\n case 'notFound': {\n // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed,\n // or the page itself was deleted.\n // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to.\n // If it is a runtime chunk list, we restart the application.\n if (runtimeChunkLists.has(chunkListPath)) {\n DEV_BACKEND.restart()\n } else {\n disposeChunkList(chunkListPath)\n }\n break\n }\n default:\n throw new Error(`Unknown update type: ${update.type}`)\n }\n}\n\nfunction createModuleHot(\n moduleId: ModuleId,\n hotData: HotData\n): { hot: Hot; hotState: HotState } {\n const hotState: HotState = {\n selfAccepted: false,\n selfDeclined: false,\n selfInvalidated: false,\n disposeHandlers: [],\n }\n\n const hot: Hot = {\n // TODO(alexkirsz) This is not defined in the HMR API. It was used to\n // decide whether to warn whenever an HMR-disposed module required other\n // modules. We might want to remove it.\n active: true,\n\n data: hotData ?? {},\n\n // TODO(alexkirsz) Support full (dep, callback, errorHandler) form.\n accept: (\n modules?: string | string[] | AcceptErrorHandler,\n _callback?: AcceptCallback,\n _errorHandler?: AcceptErrorHandler\n ) => {\n if (modules === undefined) {\n hotState.selfAccepted = true\n } else if (typeof modules === 'function') {\n hotState.selfAccepted = modules\n } else {\n throw new Error('unsupported `accept` signature')\n }\n },\n\n decline: (dep) => {\n if (dep === undefined) {\n hotState.selfDeclined = true\n } else {\n throw new Error('unsupported `decline` signature')\n }\n },\n\n dispose: (callback) => {\n hotState.disposeHandlers.push(callback)\n },\n\n addDisposeHandler: (callback) => {\n hotState.disposeHandlers.push(callback)\n },\n\n removeDisposeHandler: (callback) => {\n const idx = hotState.disposeHandlers.indexOf(callback)\n if (idx >= 0) {\n hotState.disposeHandlers.splice(idx, 1)\n }\n },\n\n invalidate: () => {\n hotState.selfInvalidated = true\n queuedInvalidatedModules.add(moduleId)\n },\n\n // NOTE(alexkirsz) This is part of the management API, which we don't\n // implement, but the Next.js React Refresh runtime uses this to decide\n // whether to schedule an update.\n status: () => 'idle',\n\n // NOTE(alexkirsz) Since we always return \"idle\" for now, these are no-ops.\n addStatusHandler: (_handler) => {},\n removeStatusHandler: (_handler) => {},\n\n // NOTE(jridgewell) Check returns the list of updated modules, but we don't\n // want the webpack code paths to ever update (the turbopack paths handle\n // this already).\n check: () => Promise.resolve(null),\n }\n\n return { hot, hotState }\n}\n\n/**\n * Removes a module from a chunk.\n * Returns `true` if there are no remaining chunks including this module.\n */\nfunction removeModuleFromChunk(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): boolean {\n const moduleChunks = moduleChunksMap.get(moduleId)!\n moduleChunks.delete(chunkPath)\n\n const chunkModules = chunkModulesMap.get(chunkPath)!\n chunkModules.delete(moduleId)\n\n const noRemainingModules = chunkModules.size === 0\n if (noRemainingModules) {\n chunkModulesMap.delete(chunkPath)\n }\n\n const noRemainingChunks = moduleChunks.size === 0\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId)\n }\n\n return noRemainingChunks\n}\n\n/**\n * Disposes of a chunk list and its corresponding exclusive chunks.\n */\nfunction disposeChunkList(chunkListPath: ChunkListPath): boolean {\n const chunkPaths = chunkListChunksMap.get(chunkListPath)\n if (chunkPaths == null) {\n return false\n }\n chunkListChunksMap.delete(chunkListPath)\n\n for (const chunkPath of chunkPaths) {\n const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!\n chunkChunkLists.delete(chunkListPath)\n\n if (chunkChunkLists.size === 0) {\n chunkChunkListsMap.delete(chunkPath)\n disposeChunk(chunkPath)\n }\n }\n\n // We must also dispose of the chunk list's chunk itself to ensure it may\n // be reloaded properly in the future.\n const chunkListUrl = getChunkRelativeUrl(chunkListPath)\n\n DEV_BACKEND.unloadChunk?.(chunkListUrl)\n\n return true\n}\n\n/**\n * Disposes of a chunk and its corresponding exclusive modules.\n *\n * @returns Whether the chunk was disposed of.\n */\nfunction disposeChunk(chunkPath: ChunkPath): boolean {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n // This should happen whether the chunk has any modules in it or not.\n // For instance, CSS chunks have no modules in them, but they still need to be unloaded.\n DEV_BACKEND.unloadChunk?.(chunkUrl)\n\n const chunkModules = chunkModulesMap.get(chunkPath)\n if (chunkModules == null) {\n return false\n }\n chunkModules.delete(chunkPath)\n\n for (const moduleId of chunkModules) {\n const moduleChunks = moduleChunksMap.get(moduleId)!\n moduleChunks.delete(chunkPath)\n\n const noRemainingChunks = moduleChunks.size === 0\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId)\n disposeModule(moduleId, 'clear')\n availableModules.delete(moduleId)\n }\n }\n\n return true\n}\n\n/**\n * Subscribes to chunk list updates from the update server and applies them.\n */\nfunction registerChunkList(chunkList: ChunkList) {\n const chunkListScript = chunkList.script\n const chunkListPath = getPathFromScript(chunkListScript)\n // The \"chunk\" is also registered to finish the loading in the backend\n BACKEND.registerChunk(chunkListPath as string as ChunkPath)\n globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!.push([\n chunkListPath,\n handleApply.bind(null, chunkListPath),\n ])\n\n // Adding chunks to chunk lists and vice versa.\n const chunkPaths = new Set(chunkList.chunks.map(getChunkPath))\n chunkListChunksMap.set(chunkListPath, chunkPaths)\n for (const chunkPath of chunkPaths) {\n let chunkChunkLists = chunkChunkListsMap.get(chunkPath)\n if (!chunkChunkLists) {\n chunkChunkLists = new Set([chunkListPath])\n chunkChunkListsMap.set(chunkPath, chunkChunkLists)\n } else {\n chunkChunkLists.add(chunkListPath)\n }\n }\n\n if (chunkList.source === 'entry') {\n markChunkListAsRuntime(chunkListPath)\n }\n}\n\nglobalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= []\n"],"names":[],"mappings":"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","ignoreList":[0]}}, + {"offset": {"line": 1468, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/dom/runtime-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n\ntype ChunkResolver = {\n resolved: boolean\n loadingStarted: boolean\n resolve: () => void\n reject: (error?: Error) => void\n promise: Promise\n}\n\nlet BACKEND: RuntimeBackend\n\nfunction augmentContext(context: unknown): unknown {\n return context\n}\n\nfunction fetchWebAssembly(wasmChunkPath: ChunkPath) {\n return fetch(getChunkRelativeUrl(wasmChunkPath))\n}\n\nasync function loadWebAssembly(\n _source: unknown,\n wasmChunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module,\n importsObj: WebAssembly.Imports\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath)\n\n const { instance } = await WebAssembly.instantiateStreaming(req, importsObj)\n\n return instance.exports\n}\n\nasync function loadWebAssemblyModule(\n _source: unknown,\n wasmChunkPath: ChunkPath,\n _edgeModule: () => WebAssembly.Module\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath)\n\n return await WebAssembly.compileStreaming(req)\n}\n\n/**\n * Maps chunk paths to the corresponding resolver.\n */\nconst chunkResolvers: Map = new Map()\n\n;(() => {\n BACKEND = {\n async registerChunk(chunkPath, params) {\n const chunkUrl = getChunkRelativeUrl(chunkPath)\n\n const resolver = getOrCreateResolver(chunkUrl)\n resolver.resolve()\n\n if (params == null) {\n return\n }\n\n for (const otherChunkData of params.otherChunks) {\n const otherChunkPath = getChunkPath(otherChunkData)\n const otherChunkUrl = getChunkRelativeUrl(otherChunkPath)\n\n // Chunk might have started loading, so we want to avoid triggering another load.\n getOrCreateResolver(otherChunkUrl)\n }\n\n // This waits for chunks to be loaded, but also marks included items as available.\n await Promise.all(\n params.otherChunks.map((otherChunkData) =>\n loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData)\n )\n )\n\n if (params.runtimeModuleIds.length > 0) {\n for (const moduleId of params.runtimeModuleIds) {\n getOrInstantiateRuntimeModule(moduleId, chunkPath)\n }\n }\n },\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n loadChunk(chunkUrl, source) {\n return doLoadChunk(chunkUrl, source)\n },\n }\n\n function getOrCreateResolver(chunkUrl: ChunkUrl): ChunkResolver {\n let resolver = chunkResolvers.get(chunkUrl)\n if (!resolver) {\n let resolve: () => void\n let reject: (error?: Error) => void\n const promise = new Promise((innerResolve, innerReject) => {\n resolve = innerResolve\n reject = innerReject\n })\n resolver = {\n resolved: false,\n loadingStarted: false,\n promise,\n resolve: () => {\n resolver!.resolved = true\n resolve()\n },\n reject: reject!,\n }\n chunkResolvers.set(chunkUrl, resolver)\n }\n return resolver\n }\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n function doLoadChunk(chunkUrl: ChunkUrl, source: SourceInfo) {\n const resolver = getOrCreateResolver(chunkUrl)\n if (resolver.loadingStarted) {\n return resolver.promise\n }\n\n if (source.type === SourceType.Runtime) {\n // We don't need to load chunks references from runtime code, as they're already\n // present in the DOM.\n resolver.loadingStarted = true\n\n if (isCss(chunkUrl)) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n }\n\n // We need to wait for JS chunks to register themselves within `registerChunk`\n // before we can start instantiating runtime modules, hence the absence of\n // `resolver.resolve()` in this branch.\n\n return resolver.promise\n }\n\n if (typeof importScripts === 'function') {\n // We're in a web worker\n if (isCss(chunkUrl)) {\n // ignore\n } else if (isJs(chunkUrl)) {\n self.TURBOPACK_NEXT_CHUNK_URLS!.push(chunkUrl)\n importScripts(TURBOPACK_WORKER_LOCATION + chunkUrl)\n } else {\n throw new Error(\n `can't infer type of chunk from URL ${chunkUrl} in worker`\n )\n }\n } else {\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl)\n\n if (isCss(chunkUrl)) {\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n )\n if (previousLinks.length > 0) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n } else {\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = chunkUrl\n link.onerror = () => {\n resolver.reject()\n }\n link.onload = () => {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve()\n }\n document.body.appendChild(link)\n }\n } else if (isJs(chunkUrl)) {\n const previousScripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n )\n if (previousScripts.length > 0) {\n // There is this edge where the script already failed loading, but we\n // can't detect that. The Promise will never resolve in this case.\n for (const script of Array.from(previousScripts)) {\n script.addEventListener('error', () => {\n resolver.reject()\n })\n }\n } else {\n const script = document.createElement('script')\n script.src = chunkUrl\n // We'll only mark the chunk as loaded once the script has been executed,\n // which happens in `registerChunk`. Hence the absence of `resolve()` in\n // this branch.\n script.onerror = () => {\n resolver.reject()\n }\n document.body.appendChild(script)\n }\n } else {\n throw new Error(`can't infer type of chunk from URL ${chunkUrl}`)\n }\n }\n\n resolver.loadingStarted = true\n return resolver.promise\n }\n})()\n"],"names":[],"mappings":"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","ignoreList":[0]}}, + {"offset": {"line": 1634, "column": 0}, "map": {"version":3,"sources":["turbopack:///[turbopack]/browser/runtime/dom/dev-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/// \n/// \n/// \n/// \n\nlet DEV_BACKEND: DevRuntimeBackend\n;(() => {\n DEV_BACKEND = {\n unloadChunk(chunkUrl) {\n deleteResolver(chunkUrl)\n\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl)\n\n if (isCss(chunkUrl)) {\n const links = document.querySelectorAll(\n `link[href=\"${chunkUrl}\"],link[href^=\"${chunkUrl}?\"],link[href=\"${decodedChunkUrl}\"],link[href^=\"${decodedChunkUrl}?\"]`\n )\n for (const link of Array.from(links)) {\n link.remove()\n }\n } else if (isJs(chunkUrl)) {\n // Unloading a JS chunk would have no effect, as it lives in the JS\n // runtime once evaluated.\n // However, we still want to remove the script tag from the DOM to keep\n // the HTML somewhat consistent from the user's perspective.\n const scripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n )\n for (const script of Array.from(scripts)) {\n script.remove()\n }\n } else {\n throw new Error(`can't infer type of chunk from URL ${chunkUrl}`)\n }\n },\n\n reloadChunk(chunkUrl) {\n return new Promise((resolve, reject) => {\n if (!isCss(chunkUrl)) {\n reject(new Error('The DOM backend can only reload CSS chunks'))\n return\n }\n\n const decodedChunkUrl = decodeURI(chunkUrl)\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n )\n\n if (previousLinks.length === 0) {\n reject(new Error(`No link element found for chunk ${chunkUrl}`))\n return\n }\n\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n\n if (navigator.userAgent.includes('Firefox')) {\n // Firefox won't reload CSS files that were previously loaded on the current page,\n // we need to add a query param to make sure CSS is actually reloaded from the server.\n //\n // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506\n //\n // Safari has a similar issue, but only if you have a `` tag\n // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726\n link.href = `${chunkUrl}?ts=${Date.now()}`\n } else {\n link.href = chunkUrl\n }\n\n link.onerror = () => {\n reject()\n }\n link.onload = () => {\n // First load the new CSS, then remove the old ones. This prevents visible\n // flickering that would happen in-between removing the previous CSS and\n // loading the new one.\n for (const previousLink of Array.from(previousLinks))\n previousLink.remove()\n\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolve()\n }\n\n // Make sure to insert the new CSS right after the previous one, so that\n // its precedence is higher.\n previousLinks[0].parentElement!.insertBefore(\n link,\n previousLinks[0].nextSibling\n )\n })\n },\n\n restart: () => self.location.reload(),\n }\n\n function deleteResolver(chunkUrl: ChunkUrl) {\n chunkResolvers.delete(chunkUrl)\n }\n})()\n\nfunction _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory {\n code += `\\n\\n//# sourceURL=${encodeURI(\n location.origin + CHUNK_BASE_PATH + url + CHUNK_SUFFIX_PATH\n )}`\n if (map) {\n code += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(\n // btoa doesn't handle nonlatin characters, so escape them as \\x sequences\n // See https://stackoverflow.com/a/26603875\n unescape(encodeURIComponent(map))\n )}`\n }\n\n // eslint-disable-next-line no-eval\n return eval(code)\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,oDAAoD,GAEpD,gDAAgD;AAChD,4CAA4C;AAC5C,iDAAiD;AACjD,0DAA0D;AAE1D,IAAI;AACH,CAAC;IACA,cAAc;QACZ,aAAY,QAAQ;YAClB,eAAe;YAEf,gFAAgF;YAChF,MAAM,kBAAkB,UAAU;YAElC,IAAI,MAAM,WAAW;gBACnB,MAAM,QAAQ,SAAS,gBAAgB,CACrC,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,SAAS,eAAe,EAAE,gBAAgB,eAAe,EAAE,gBAAgB,GAAG,CAAC;gBAEzH,KAAK,MAAM,QAAQ,MAAM,IAAI,CAAC,OAAQ;oBACpC,KAAK,MAAM;gBACb;YACF,OAAO,IAAI,KAAK,WAAW;gBACzB,mEAAmE;gBACnE,0BAA0B;gBAC1B,uEAAuE;gBACvE,4DAA4D;gBAC5D,MAAM,UAAU,SAAS,gBAAgB,CACvC,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB,EAAE,gBAAgB,gBAAgB,EAAE,gBAAgB,GAAG,CAAC;gBAE7H,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,SAAU;oBACxC,OAAO,MAAM;gBACf;YACF,OAAO;gBACL,MAAM,IAAI,MAAM,CAAC,mCAAmC,EAAE,UAAU;YAClE;QACF;QAEA,aAAY,QAAQ;YAClB,OAAO,IAAI,QAAc,CAAC,SAAS;gBACjC,IAAI,CAAC,MAAM,WAAW;oBACpB,OAAO,IAAI,MAAM;oBACjB;gBACF;gBAEA,MAAM,kBAAkB,UAAU;gBAClC,MAAM,gBAAgB,SAAS,gBAAgB,CAC7C,CAAC,2BAA2B,EAAE,SAAS,+BAA+B,EAAE,SAAS,+BAA+B,EAAE,gBAAgB,+BAA+B,EAAE,gBAAgB,GAAG,CAAC;gBAGzL,IAAI,cAAc,MAAM,KAAK,GAAG;oBAC9B,OAAO,IAAI,MAAM,CAAC,gCAAgC,EAAE,UAAU;oBAC9D;gBACF;gBAEA,MAAM,OAAO,SAAS,aAAa,CAAC;gBACpC,KAAK,GAAG,GAAG;gBAEX,IAAI,UAAU,SAAS,CAAC,QAAQ,CAAC,YAAY;oBAC3C,kFAAkF;oBAClF,sFAAsF;oBACtF,EAAE;oBACF,qFAAqF;oBACrF,EAAE;oBACF,oFAAoF;oBACpF,6FAA6F;oBAC7F,KAAK,IAAI,GAAG,GAAG,SAAS,IAAI,EAAE,KAAK,GAAG,IAAI;gBAC5C,OAAO;oBACL,KAAK,IAAI,GAAG;gBACd;gBAEA,KAAK,OAAO,GAAG;oBACb;gBACF;gBACA,KAAK,MAAM,GAAG;oBACZ,0EAA0E;oBAC1E,wEAAwE;oBACxE,uBAAuB;oBACvB,KAAK,MAAM,gBAAgB,MAAM,IAAI,CAAC,eACpC,aAAa,MAAM;oBAErB,uEAAuE;oBACvE,oBAAoB;oBACpB;gBACF;gBAEA,wEAAwE;gBACxE,4BAA4B;gBAC5B,aAAa,CAAC,EAAE,CAAC,aAAa,CAAE,YAAY,CAC1C,MACA,aAAa,CAAC,EAAE,CAAC,WAAW;YAEhC;QACF;QAEA,SAAS,IAAM,KAAK,QAAQ,CAAC,MAAM;IACrC;IAEA,SAAS,eAAe,QAAkB;QACxC,eAAe,MAAM,CAAC;IACxB;AACF,CAAC;AAED,SAAS,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAyB;IACtD,QAAQ,CAAC,kBAAkB,EAAE,UAC3B,SAAS,MAAM,GAAG,kBAAkB,MAAM,oBACzC;IACH,IAAI,KAAK;QACP,QAAQ,CAAC,kEAAkE,EAAE,KAC3E,0EAA0E;QAC1E,2CAA2C;QAC3C,SAAS,mBAAmB,QAC3B;IACL;IAEA,mCAAmC;IACnC,OAAO,KAAK;AACd","ignoreList":[0]}}] } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js index 9c1bc13a335b1..118290bd18d4d 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "default": (()=>MyApp) + "default": ()=>MyApp }); var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)"); ; @@ -28,18 +28,21 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbo ; console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$packages$2f$component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$node_modules$2f$third_party_component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]); }), -"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)": (function(__turbopack_context__) { +"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)": ((__turbopack_context__) => { +"use strict"; -var { m: module, e: exports } = __turbopack_context__; -{ -"purposefully empty stub"; -"react/jsx-dev-runtime.js"; -}}), +__turbopack_context__.s({ + "jsxDEV": ()=>jsxDEV +}); +function jsxDEV() { + return 'purposefully empty stub for react/jsx-dev-runtime.js'; +} +}), "[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js [test] (ecmascript)": ((__turbopack_context__) => { "use strict"; __turbopack_context__.s({ - "default": (()=>ThirdPartyComponent) + "default": ()=>ThirdPartyComponent }); function ThirdPartyComponent() { return
Should not be transformed
; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js.map index 585b7febcdb86..12ad385ff9596 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js.map +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/turbopack_crates_turbopack-tests_tests_snapshot_b56e07c9._.js.map @@ -4,6 +4,6 @@ "sections": [ {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js"],"sourcesContent":["export default function MyApp() {\n return
App
\n}\n"],"names":[],"mappings":";;;;;AAAe,SAAS;IACtB,qBAAO,0NAAC;kBAAI;;;;;;AACd"}}, {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js"],"sourcesContent":["import MyApp from 'component'\nimport ThirdPartyComponent from 'third_party_component'\n\nconsole.log(MyApp, ThirdPartyComponent)\n"],"names":[],"mappings":";AAAA;AACA;;;AAEA,QAAQ,GAAG,CAAC,wOAAA,CAAA,UAAK,EAAE,wPAAA,CAAA,UAAmB"}}, - {"offset": {"line": 34, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}, - {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js"],"sourcesContent":["export default function ThirdPartyComponent() {\n return
Should not be transformed
;\n}\n"],"names":[],"mappings":";;;AAAe,SAAS;IACtB,QAAQ,IAAI,yBAAyB,EAAE;AACzC","ignoreList":[0]}}] + {"offset": {"line": 33, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["export function jsxDEV() {\n return 'purposefully empty stub for react/jsx-dev-runtime.js'\n}\n"],"names":[],"mappings":";;;AAAO,SAAS;IACd,OAAO;AACT","ignoreList":[0]}}, + {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js"],"sourcesContent":["export default function ThirdPartyComponent() {\n return
Should not be transformed
;\n}\n"],"names":[],"mappings":";;;AAAe,SAAS;IACtB,QAAQ,IAAI,yBAAyB,EAAE;AACzC","ignoreList":[0]}}] } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js index dcb6bd0d1874b..c7981dada0781 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js @@ -12,13 +12,16 @@ var Foo = function Foo() { }; console.log(Foo, [].includes('foo')); }), -"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)": (function(__turbopack_context__) { +"[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)": ((__turbopack_context__) => { +"use strict"; -var { m: module, e: exports } = __turbopack_context__; -{ -"purposefully empty stub"; -"@swc/helpers/_/_class_call_check.js"; -}}), +__turbopack_context__.s({ + "_": ()=>_ +}); +function _() { + return 'purposefully empty stub for @swc/helpers/_/_class_call_check.js'; +} +}), }]); //# sourceMappingURL=turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js.map index d0f5bcb671710..e115849ea0d96 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js.map +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/turbopack_crates_turbopack-tests_tests_snapshot_bff03a32._.js.map @@ -3,5 +3,5 @@ "sources": [], "sections": [ {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js"],"sourcesContent":["class Foo {}\n\nconsole.log(Foo, [].includes('foo'))\n"],"names":[],"mappings":";;;AAAA,IAAA,AAAM,MAAN,SAAM;;2OAAA;;AAEN,QAAQ,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC"}}, - {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@swc/helpers/_/_class_call_check.js\";\n"],"names":[],"mappings":"AAAA;AACA","ignoreList":[0]}}] + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack:///[project]/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js"],"sourcesContent":["export function _() {\n return 'purposefully empty stub for @swc/helpers/_/_class_call_check.js'\n}\n"],"names":[],"mappings":";;;AAAO,SAAS;IACd,OAAO;AACT","ignoreList":[0]}}] } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_50efc170._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_50efc170._.js index 0dc7cc0b96ddf..18ef60a9856e7 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_50efc170._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_50efc170._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_88264193._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_88264193._.js index 86b0571c4b443..9efdec5c97ee1 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_88264193._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_88264193._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), @@ -24,7 +24,7 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "bar": (()=>bar) + "bar": ()=>bar }); const bar = 'bar'; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/turbopack_crates_turbopack-tests_tests_snapshot_f038421b._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/turbopack_crates_turbopack-tests_tests_snapshot_f038421b._.js index 8eb4a0cb62577..878cb47fa8285 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/turbopack_crates_turbopack-tests_tests_snapshot_f038421b._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/turbopack_crates_turbopack-tests_tests_snapshot_f038421b._.js @@ -14,7 +14,7 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/turbopack_crates_turbopack-tests_tests_snapshot_cff3cff1._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/turbopack_crates_turbopack-tests_tests_snapshot_cff3cff1._.js index a79a881c0860d..196b10070413a 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/turbopack_crates_turbopack-tests_tests_snapshot_cff3cff1._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/turbopack_crates_turbopack-tests_tests_snapshot_cff3cff1._.js @@ -14,7 +14,7 @@ console.log(__TURBOPACK__imported__module__$5b$project$5d2f$turbopack$2f$crates$ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/4c35f_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_ef6815c7._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/4c35f_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_ef6815c7._.js index fa745ddc0cc64..c5a442187e6c3 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/4c35f_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_ef6815c7._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/4c35f_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_ef6815c7._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/4c35f_tests_snapshot_typescript_tsconfig-extends-without-ext_input_fcdb4390._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/4c35f_tests_snapshot_typescript_tsconfig-extends-without-ext_input_fcdb4390._.js index 9b4f3e3972a36..55a1af87c41c2 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/4c35f_tests_snapshot_typescript_tsconfig-extends-without-ext_input_fcdb4390._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/4c35f_tests_snapshot_typescript_tsconfig-extends-without-ext_input_fcdb4390._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_39e68707._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_39e68707._.js index 1f028cb69ca24..9f8c271dad820 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_39e68707._.js +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/b1abf_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_39e68707._.js @@ -4,7 +4,7 @@ "use strict"; __turbopack_context__.s({ - "prop": (()=>prop) + "prop": ()=>prop }); const prop = 1; }), From 4744ec5afa0388d7723f4d5e82e5c45122f675ba Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 30 May 2025 09:12:28 +0200 Subject: [PATCH 50/59] Fix availability info --- .../crates/turbopack-core/src/chunk/chunk_group.rs | 14 ++++++++------ turbopack/crates/turbopack-core/src/chunk/mod.rs | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs index be29d0f2c3c4e..197846a615d46 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs @@ -54,6 +54,7 @@ pub async fn make_chunk_group( batch_groups, async_modules, traced_modules, + availability_info, } = chunk_group_content( module_graph, chunk_group_entries.clone(), @@ -98,11 +99,6 @@ pub async fn make_chunk_group( .try_join() .await?; - // Compute new [AvailabilityInfo] - let availability_info = availability_info - .with_modules(Vc::cell(chunkable_items)) - .await?; - // Insert async chunk loaders for every referenced async module let async_loaders = async_modules .into_iter() @@ -319,6 +315,11 @@ pub async fn chunk_group_content( }, )?; + // This needs to use the unmerged items + let availability_info = availability_info + .with_modules(Vc::cell(state.chunkable_items.clone())) + .await?; + if should_merge_modules { let merged_modules = module_graph.merged_modules().await?; // let old_items: Vec>> = state @@ -417,7 +418,7 @@ pub async fn chunk_group_content( .await? .into_iter() .collect(); - } + }; let mut batch_groups = FxIndexSet::default(); for &module in &state.chunkable_items { @@ -431,5 +432,6 @@ pub async fn chunk_group_content( batch_groups, async_modules: state.async_modules, traced_modules: state.traced_modules, + availability_info, }) } diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 2ec304dda3693..47d625fed62bd 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -36,6 +36,7 @@ pub use self::{ }; use crate::{ asset::Asset, + chunk::availability_info::AvailabilityInfo, ident::AssetIdent, module::Module, module_graph::{ @@ -339,12 +340,12 @@ pub trait ChunkableModuleReference: ModuleReference + ValueToString { } } -#[derive(Default)] pub struct ChunkGroupContent { pub chunkable_items: FxIndexSet, pub batch_groups: FxIndexSet>, pub async_modules: FxIndexSet>>, pub traced_modules: FxIndexSet>>, + pub availability_info: AvailabilityInfo, } #[turbo_tasks::value_trait] From ae9c5c139a4b93b34261c0f5b70a11bf9566a157 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 2 Jun 2025 10:47:00 +0200 Subject: [PATCH 51/59] Improve error message --- turbopack/crates/turbopack-ecmascript/src/chunk/item.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs index 9b1bebe35b563..b7b46e7683471 100644 --- a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs @@ -270,11 +270,7 @@ async fn module_factory_with_code_generation_issue( { Ok(factory) => factory, Err(error) => { - let id = chunk_item - .chunking_context() - .chunk_item_id(Vc::upcast(chunk_item)) - .to_string() - .await; + let id = chunk_item.asset_ident().to_string().await; let id = id.as_ref().map_or_else(|_| "unknown", |id| &**id); let error = error.context(format!( "An error occurred while generating the chunk item {id}" From eec3f096a4a566351c405ef0d2909cd960f93a27 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 2 Jun 2025 11:04:39 +0200 Subject: [PATCH 52/59] Review feedback --- Cargo.lock | 1 + .../crates/turbopack-ecmascript/Cargo.toml | 1 + .../crates/turbopack-ecmascript/src/lib.rs | 26 +++++++++------- .../src/references/async_module.rs | 23 +++++++------- .../crates/turbopack-ecmascript/src/utils.rs | 30 +++++++++++++++++-- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfbc398fe9c2b..e034e0ab9523b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10135,6 +10135,7 @@ dependencies = [ "either", "indexmap 2.7.1", "indoc", + "itertools 0.10.5", "lazy_static", "num-bigint", "num-traits", diff --git a/turbopack/crates/turbopack-ecmascript/Cargo.toml b/turbopack/crates/turbopack-ecmascript/Cargo.toml index fd34161434f2c..591717ce35ce2 100644 --- a/turbopack/crates/turbopack-ecmascript/Cargo.toml +++ b/turbopack/crates/turbopack-ecmascript/Cargo.toml @@ -20,6 +20,7 @@ data-encoding = { workspace = true } either = { workspace = true } indexmap = { workspace = true } indoc = { workspace = true } +itertools = { workspace = true } lazy_static = { workspace = true } num-bigint = "0.4" num-traits = "0.2.15" diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 6f10cb058b4e4..49dc14fac7098 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -41,10 +41,11 @@ use std::{ sync::Arc, }; -use anyhow::{Context, Result}; +use anyhow::{Context, Result, bail}; use chunk::EcmascriptChunkItem; use code_gen::{CodeGeneration, CodeGenerationHoistedStmt}; use either::Either; +use itertools::Itertools; use parse::{ParseResult, parse}; use path_visitor::ApplyVisitors; use references::esm::UrlRewriteBehavior; @@ -1134,6 +1135,10 @@ impl EcmascriptModuleContent { /// Creates a new [`Vc`] from multiple modules, performing scope /// hoisting. + /// - The `modules` argument is a list of all modules to be merged (and whethey their exports + /// should be exposed). + /// - The `entries` argument is a list of modules that should be treated as entry points for the + /// merged module (used to determine execution order). #[turbo_tasks::function] pub async fn new_merged( modules: Vec<(ResolvedVc>, bool)>, @@ -1186,7 +1191,7 @@ impl EcmascriptModuleContent { let globals = if let ParseResult::Ok { globals, .. } = &*var_name { globals } else { - unreachable!() + bail!("expected ParseResult::Ok"); }; let (is_export_mark, module_syntax_contexts) = GLOBALS.set(globals, || { let is_export_mark = Mark::new(); @@ -1288,11 +1293,11 @@ async fn merge_modules( ) -> Result { struct SetSyntaxContextVisitor<'a> { current_module: ResolvedVc>, - // A marker to quickly identify the special cross-module variable references + /// A marker to quickly identify the special cross-module variable references export_mark: Mark, - // The syntax contexts in the merged AST (each module has its own) + /// The syntax contexts in the merged AST (each module has its own) merged_ctxts: &'a FxIndexMap>, SyntaxContext>, - // The export syntax contexts in the current AST, which will be mapped to merged_ctxts + /// The export syntax contexts in the current AST, which will be mapped to merged_ctxts current_module_contexts: &'a FxIndexMap>, SyntaxContext>, } @@ -1335,9 +1340,9 @@ async fn merge_modules( }); }); - content.take().body + Ok(content.take().body) } else { - unreachable!() + bail!("Expected Program::Module"); } }; @@ -1350,8 +1355,9 @@ async fn merge_modules( shebang: None, body: entries .iter() - .flat_map(|(_, i)| prepare_module(&mut contents[*i])) - .collect(), + .map(|(_, i)| prepare_module(&mut contents[*i])) + .flatten_ok() + .collect::>>()?, }; // Replace inserted `__turbopack_merged_esm__(i);` statements with the corresponding ith-module @@ -1372,7 +1378,7 @@ async fn merge_modules( if inserted.insert(index) { let module = &mut contents[index]; - merged_ast.body.splice(i..=i, prepare_module(module)); + merged_ast.body.splice(i..=i, prepare_module(module)?); // Don't increment, the ith item has just changed continue; diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index 227322ae6320d..1d9204e124ec2 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -1,7 +1,7 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use swc_core::{ - common::{DUMMY_SP, SyntaxContext}, + common::DUMMY_SP, ecma::ast::{ArrayLit, ArrayPat, Expr, Ident}, quote, }; @@ -16,7 +16,10 @@ use turbopack_core::{ }; use super::esm::base::ReferencedAsset; -use crate::code_gen::{CodeGeneration, CodeGenerationHoistedStmt}; +use crate::{ + code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, + utils::AstSyntaxContext, +}; /// Information needed for generating the async module wrapper for /// [EcmascriptChunkItem](crate::chunk::EcmascriptChunkItem)s. @@ -75,8 +78,10 @@ impl OptionAsyncModule { } } +/// The identifiers (and their corresponding syntax context) of all async modules referenced by the +/// current module. #[turbo_tasks::value(transparent)] -struct AsyncModuleIdents(FxIndexSet<(String, u32)>); +struct AsyncModuleIdents(FxIndexSet<(String, AstSyntaxContext)>); async fn get_inherit_async_referenced_asset( r: Vc>, @@ -126,7 +131,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) - .map(|(i, ctx)| (i, ctx.unwrap_or_default().as_u32())) + .map(|(i, ctx)| (i, ctx.unwrap_or_default().into())) } else { None } @@ -140,7 +145,7 @@ impl AsyncModule { .get_ident(chunking_context, None, None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) - .map(|(i, ctx)| (i, ctx.unwrap_or_default().as_u32())) + .map(|(i, ctx)| (i, ctx.unwrap_or_default().into())) } else { None } @@ -215,13 +220,7 @@ impl AsyncModule { if !async_idents.is_empty() { let idents = async_idents .iter() - .map(|(ident, ctxt)| { - Ident::new( - ident.clone().into(), - DUMMY_SP, - SyntaxContext::from_u32(*ctxt), - ) - }) + .map(|(ident, ctxt)| Ident::new(ident.clone().into(), DUMMY_SP, **ctxt)) .collect::>(); return Ok(CodeGeneration::hoisted_stmts([ diff --git a/turbopack/crates/turbopack-ecmascript/src/utils.rs b/turbopack/crates/turbopack-ecmascript/src/utils.rs index 78f5e711ea4ef..b484b7c58fe24 100644 --- a/turbopack/crates/turbopack-ecmascript/src/utils.rs +++ b/turbopack/crates/turbopack-ecmascript/src/utils.rs @@ -1,12 +1,14 @@ +use std::ops::Deref; + use serde::{Deserialize, Serialize}; use swc_core::{ - common::DUMMY_SP, + common::{DUMMY_SP, SyntaxContext}, ecma::{ ast::{Expr, Lit, Str}, visit::AstParentKind, }, }; -use turbo_tasks::{NonLocalValue, trace::TraceRawVcs}; +use turbo_tasks::{NonLocalValue, TaskInput, trace::TraceRawVcs}; use turbopack_core::{chunk::ModuleId, resolve::pattern::Pattern}; use crate::analyzer::{ @@ -200,3 +202,27 @@ pub fn module_value_to_well_known_object(module_value: &ModuleValue) -> Option return None, }) } + +#[derive(Hash, Debug, Clone, Copy, Eq, Serialize, Deserialize, PartialEq, TraceRawVcs)] +pub struct AstSyntaxContext(#[turbo_tasks(trace_ignore)] SyntaxContext); + +impl TaskInput for AstSyntaxContext { + fn is_transient(&self) -> bool { + false + } +} +unsafe impl NonLocalValue for AstSyntaxContext {} + +impl Deref for AstSyntaxContext { + type Target = SyntaxContext; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for AstSyntaxContext { + fn from(v: SyntaxContext) -> Self { + Self(v) + } +} From f4a1bb0ffde5ab9f887ccd05a10b2f95b8239ba1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 2 Jun 2025 14:44:11 +0200 Subject: [PATCH 53/59] Don't mutate the globals in the cell --- .../crates/turbopack-ecmascript/src/lib.rs | 441 ++++++++++-------- 1 file changed, 246 insertions(+), 195 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 49dc14fac7098..ea2562f11edb0 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -109,6 +109,7 @@ pub use turbopack_resolve::ecmascript as resolve; use self::chunk::{EcmascriptChunkItemContent, EcmascriptChunkType, EcmascriptExports}; use crate::{ + analyzer::graph::EvalContext, chunk::{EcmascriptChunkPlaceable, placeable::is_marked_as_side_effect_free}, code_gen::{CodeGens, ModifiableAst}, merged_module::MergedEcmascriptModule, @@ -1090,7 +1091,6 @@ impl EcmascriptModuleContent { .. } = &*input; - let code_gens = input.merged_code_gens(None).await?; async { let minify = chunking_context.minify_type().await?; @@ -1098,10 +1098,10 @@ impl EcmascriptModuleContent { *parsed, **ident, *specified_module_type, - code_gens, *generate_source_map, *original_source_map, *minify, + Some(&*input), None, ) .await?; @@ -1123,11 +1123,11 @@ impl EcmascriptModuleContent { parsed.to_resolved().await?, ident, specified_module_type, - vec![], generate_source_map, None, MinifyType::NoMinify, None, + None, ) .await?; emit_content(content, Default::default()).await @@ -1187,61 +1187,23 @@ impl EcmascriptModuleContent { original_source_map, .. } = &*options; - let var_name = parsed.await?; - let globals = if let ParseResult::Ok { globals, .. } = &*var_name { - globals - } else { - bail!("expected ParseResult::Ok"); - }; - let (is_export_mark, module_syntax_contexts) = GLOBALS.set(globals, || { - let is_export_mark = Mark::new(); - let module_syntax_contexts: FxIndexMap<_, _> = modules - .keys() - .map(|m| { - let mark = Mark::fresh(is_export_mark); - ( - *m, - SyntaxContext::empty() - .apply_mark(is_export_mark) - .apply_mark(mark), - ) - }) - .collect(); - (is_export_mark, module_syntax_contexts) - }); - let ctx = ScopeHoistingContext { - module, - modules: &modules, - module_syntax_contexts: &module_syntax_contexts, - }; - let code_gens = options.merged_code_gens(Some(ctx)).await?; - let preserved_exports = match &*module.get_exports().await? { - EcmascriptExports::EsmExports(exports) => exports - .await? - .exports - .iter() - .flat_map(|(_, e)| { - if let export::EsmExport::LocalBinding(n, _) = e { - Some(Atom::from(&**n)) - } else { - None - } - }) - .collect(), - _ => Default::default(), - }; + let result = process_parse_result( *parsed, **ident, *specified_module_type, - code_gens, *generate_source_map, *original_source_map, *chunking_context.minify_type().await?, - Some((is_export_mark, preserved_exports)), + Some(&*options), + Some(ScopeHoistingOptions { + module, + modules: &modules, + }), ) .await?; - Ok((module, module_syntax_contexts, is_export_mark, result)) + + Ok((module, result)) }) .try_join() .await?; @@ -1265,6 +1227,7 @@ impl EcmascriptModuleContent { .minify_type() .await?, extra_comments: SwcComments::default(), + scope_hoisting_syntax_contexts: None, }; let chunking_context = module_options.last().unwrap().await?.chunking_context; let additional_ids = modules @@ -1281,12 +1244,7 @@ impl EcmascriptModuleContent { #[allow(clippy::type_complexity)] async fn merge_modules( - mut contents: Vec<( - ResolvedVc>, - FxIndexMap>, SyntaxContext>, - Mark, - CodeGenResult, - )>, + mut contents: Vec<(ResolvedVc>, CodeGenResult)>, entries: Vec<(ResolvedVc>, usize)>, merged_ctxts: &'_ FxIndexMap>, SyntaxContext>, globals_merged: &'_ Globals, @@ -1316,35 +1274,31 @@ async fn merge_modules( *ctxt = *self.merged_ctxts.get(&module).unwrap(); } - // fn visit_mut_span(&mut self, span: &mut Span) {} } - let prepare_module = |(module, module_contexts, export_mark, content): &mut ( - ResolvedVc>, - FxIndexMap>, SyntaxContext>, - Mark, - CodeGenResult, - )| { - if let CodeGenResult { - program: Program::Module(content), - globals, - .. - } = content - { - GLOBALS.set(&*globals, || { - content.visit_mut_with(&mut SetSyntaxContextVisitor { - current_module: *module, - export_mark: *export_mark, - merged_ctxts, - current_module_contexts: module_contexts, + let prepare_module = + |(module, content): &mut (ResolvedVc>, CodeGenResult)| { + if let CodeGenResult { + program: Program::Module(content), + globals, + scope_hoisting_syntax_contexts: Some((export_mark, module_contexts)), + .. + } = content + { + GLOBALS.set(&*globals, || { + content.visit_mut_with(&mut SetSyntaxContextVisitor { + current_module: *module, + export_mark: *export_mark, + merged_ctxts, + current_module_contexts: module_contexts, + }); }); - }); - Ok(content.take().body) - } else { - bail!("Expected Program::Module"); - } - }; + Ok(content.take().body) + } else { + bail!("Expected Program::Module with scope_hosting_syntax_contexts"); + } + }; let mut inserted = FxHashSet::with_capacity_and_hasher(contents.len(), Default::default()); @@ -1442,72 +1396,93 @@ struct CodeGenResult { generate_source_map: bool, original_source_map: Option>>, minify: MinifyType, + #[allow(clippy::type_complexity)] + scope_hoisting_syntax_contexts: Option<( + Mark, + FxIndexMap>, SyntaxContext>, + )>, +} + +struct ScopeHoistingOptions<'a> { + module: ResolvedVc>, + modules: &'a FxIndexMap>, bool>, } async fn process_parse_result( parsed: ResolvedVc, ident: Vc, specified_module_type: SpecifiedModuleType, - mut code_gens: Vec, generate_source_map: bool, original_source_map: Option>>, minify: MinifyType, - retain_syntax_context: Option<(Mark, FxHashSet)>, + options: Option<&EcmascriptModuleContentOptions>, + scope_hoisting_options: Option>, ) -> Result { - let parsed = parsed.final_read_hint().await?; + with_consumed_parse_result( + parsed, + async |mut program, source_map, globals, eval_context, comments| -> Result { + let (mut code_gens, retain_syntax_context) = if let Some(scope_hoisting_options) = + scope_hoisting_options + { + let (is_export_mark, module_syntax_contexts) = GLOBALS.set(&globals, || { + let is_export_mark = Mark::new(); + let module_syntax_contexts: FxIndexMap<_, _> = scope_hoisting_options + .modules + .keys() + .map(|m| { + let mark = Mark::fresh(is_export_mark); + ( + *m, + SyntaxContext::empty() + .apply_mark(is_export_mark) + .apply_mark(mark), + ) + }) + .collect(); + (is_export_mark, module_syntax_contexts) + }); + + let ctx = ScopeHoistingContext { + module: scope_hoisting_options.module, + modules: scope_hoisting_options.modules, + module_syntax_contexts: &module_syntax_contexts, + }; + let code_gens = options.unwrap().merged_code_gens(Some(ctx)).await?; + let preserved_exports = match &*scope_hoisting_options.module.get_exports().await? { + EcmascriptExports::EsmExports(exports) => exports + .await? + .exports + .iter() + .flat_map(|(_, e)| { + if let export::EsmExport::LocalBinding(n, _) = e { + Some(Atom::from(&**n)) + } else { + None + } + }) + .collect(), + _ => Default::default(), + }; + + ( + code_gens, + Some((is_export_mark, module_syntax_contexts, preserved_exports)), + ) + } else if let Some(options) = options { + (options.merged_code_gens(None).await?, None) + } else { + (vec![], None) + }; - Ok(match &*parsed { - ParseResult::Ok { .. } => { let extra_comments = SwcComments { leading: Default::default(), trailing: Default::default(), }; - // We need a mutable version of the AST. We try to avoid cloning it by unwrapping the - // ReadRef. - let mut parsed = ReadRef::try_unwrap(parsed); - let (mut program, source_map, globals, eval_context, comments) = match &mut parsed { - Ok(ParseResult::Ok { - program, - source_map, - globals, - eval_context, - comments, - }) => ( - program.take(), - &*source_map, - &*globals, - &*eval_context, - match Arc::try_unwrap(take(comments)) { - Ok(comments) => Either::Left(comments), - Err(comments) => Either::Right(comments), - }, - ), - Err(parsed) => { - let ParseResult::Ok { - program, - source_map, - globals, - eval_context, - comments, - } = &**parsed - else { - unreachable!(); - }; - ( - program.clone(), - source_map, - globals, - eval_context, - Either::Right(comments.clone()), - ) - } - _ => unreachable!(), - }; let top_level_mark = eval_context.top_level_mark; let is_esm = eval_context.is_esm(specified_module_type); - process_content_with_code_gens(&mut program, globals, &mut code_gens); + process_content_with_code_gens(&mut program, &globals, &mut code_gens); for comments in code_gens.iter_mut().flat_map(|cg| cg.comments.as_mut()) { let leading = Arc::unwrap_or_clone(take(&mut comments.leading)); @@ -1522,11 +1497,11 @@ async fn process_parse_result( } } - GLOBALS.set(globals, || { - if let Some((is_export_mark, preserved_symbols)) = retain_syntax_context { + GLOBALS.set(&globals, || { + if let Some((is_export_mark, _, preserved_symbols)) = &retain_syntax_context { program.visit_mut_with(&mut hygiene_rename_only( Some(top_level_mark), - is_export_mark, + *is_export_mark, preserved_symbols, )); } else { @@ -1549,78 +1524,153 @@ async fn process_parse_result( remove_shebang(&mut program); }); - CodeGenResult { + Ok(CodeGenResult { program, source_map: source_map.clone(), - globals: globals.clone(), + globals: Arc::new(globals), comments, extra_comments, is_esm, generate_source_map, original_source_map, minify, - } - } - ParseResult::Unparseable { messages } => { - let path = ident.path().to_string().await?; - let error_messages = messages - .as_ref() - .and_then(|m| m.first().map(|f| format!("\n{f}"))) - .unwrap_or("".into()); - let msg = format!("Could not parse module '{path}'\n{error_messages}"); - let body = vec![ - quote!( - "const e = new Error($msg);" as Stmt, - msg: Expr = Expr::Lit(msg.into()), - ), - quote!("e.code = 'MODULE_UNPARSEABLE';" as Stmt), - quote!("throw e;" as Stmt), - ]; + scope_hoisting_syntax_contexts: retain_syntax_context + .map(|(mark, ctxts, _)| (mark, ctxts)), + }) + }, + async |parse_result| -> Result { + Ok(match parse_result { + ParseResult::Ok { .. } => unreachable!(), + ParseResult::Unparseable { messages } => { + let path = ident.path().to_string().await?; + let error_messages = messages + .as_ref() + .and_then(|m| m.first().map(|f| format!("\n{f}"))) + .unwrap_or("".into()); + let msg = format!("Could not parse module '{path}'\n{error_messages}"); + let body = vec![ + quote!( + "const e = new Error($msg);" as Stmt, + msg: Expr = Expr::Lit(msg.into()), + ), + quote!("e.code = 'MODULE_UNPARSEABLE';" as Stmt), + quote!("throw e;" as Stmt), + ]; + + CodeGenResult { + program: Program::Script(Script { + span: DUMMY_SP, + body, + shebang: None, + }), + source_map: Arc::new(SourceMap::default()), + globals: Arc::new(Globals::default()), + comments: Either::Left(Default::default()), + extra_comments: Default::default(), + is_esm: false, + generate_source_map: false, + original_source_map: None, + minify: MinifyType::NoMinify, + scope_hoisting_syntax_contexts: None, + } + } + ParseResult::NotFound => { + let path = ident.path().to_string().await?; + let msg = format!("Could not parse module '{path}'"); + let body = vec![ + quote!( + "const e = new Error($msg);" as Stmt, + msg: Expr = Expr::Lit(msg.into()), + ), + quote!("e.code = 'MODULE_UNPARSEABLE';" as Stmt), + quote!("throw e;" as Stmt), + ]; + CodeGenResult { + program: Program::Script(Script { + span: DUMMY_SP, + body, + shebang: None, + }), + source_map: Arc::new(SourceMap::default()), + globals: Arc::new(Globals::default()), + comments: Either::Left(Default::default()), + extra_comments: Default::default(), + is_esm: false, + generate_source_map: false, + original_source_map: None, + minify: MinifyType::NoMinify, + scope_hoisting_syntax_contexts: None, + } + } + }) + }, + ) + .await +} - CodeGenResult { - program: Program::Script(Script { - span: DUMMY_SP, - body, - shebang: None, - }), - source_map: Arc::new(SourceMap::default()), - globals: Arc::new(Globals::default()), - comments: Either::Left(Default::default()), - extra_comments: Default::default(), - is_esm: false, - generate_source_map: false, - original_source_map: None, - minify: MinifyType::NoMinify, - } - } - ParseResult::NotFound => { - let path = ident.path().to_string().await?; - let msg = format!("Could not parse module '{path}'"); - let body = vec![ - quote!( - "const e = new Error($msg);" as Stmt, - msg: Expr = Expr::Lit(msg.into()), +/// Try to avoid cloning the AST and Globals by unwrapping the ReadRef. +async fn with_consumed_parse_result( + parsed: ResolvedVc, + success: impl AsyncFnOnce( + Program, + &Arc, + Globals, + &EvalContext, + Either>, + ) -> Result, + error: impl AsyncFnOnce(&ParseResult) -> Result, +) -> Result { + let parsed = parsed.final_read_hint().await?; + match &*parsed { + ParseResult::Ok { .. } => { + let mut parsed = ReadRef::try_unwrap(parsed); + let (program, source_map, globals, eval_context, comments) = match &mut parsed { + Ok(ParseResult::Ok { + program, + source_map, + globals, + eval_context, + comments, + }) => ( + program.take(), + &*source_map, + // TODO? + // Arc::get_mut(globals) + // .take() + // .map_or_else(|| globals.clone_data(), |v| std::mem::take(v)), + globals.clone_data(), + &*eval_context, + match Arc::try_unwrap(take(comments)) { + Ok(comments) => Either::Left(comments), + Err(comments) => Either::Right(comments), + }, ), - quote!("e.code = 'MODULE_UNPARSEABLE';" as Stmt), - quote!("throw e;" as Stmt), - ]; - CodeGenResult { - program: Program::Script(Script { - span: DUMMY_SP, - body, - shebang: None, - }), - source_map: Arc::new(SourceMap::default()), - globals: Arc::new(Globals::default()), - comments: Either::Left(Default::default()), - extra_comments: Default::default(), - is_esm: false, - generate_source_map: false, - original_source_map: None, - minify: MinifyType::NoMinify, - } + Err(parsed) => { + let ParseResult::Ok { + program, + source_map, + globals, + eval_context, + comments, + } = &**parsed + else { + unreachable!(); + }; + ( + program.clone(), + source_map, + globals.clone_data(), + eval_context, + Either::Right(comments.clone()), + ) + } + _ => unreachable!(), + }; + + success(program, source_map, globals, eval_context, comments).await } - }) + _ => error(&parsed).await, + } } async fn emit_content( @@ -1637,6 +1687,7 @@ async fn emit_content( original_source_map, minify, globals: _, + scope_hoisting_syntax_contexts: _, } = content; let mut bytes: Vec = vec![]; @@ -1778,13 +1829,13 @@ fn process_content_with_code_gens( fn hygiene_rename_only( top_level_mark: Option, is_export_mark: Mark, - preserved_symbols: FxHashSet, + preserved_symbols: &FxHashSet, ) -> impl VisitMut { - struct HygieneRenamer { - preserved_symbols: FxHashSet, + struct HygieneRenamer<'a> { + preserved_symbols: &'a FxHashSet, is_export_mark: Mark, } - impl swc_core::ecma::transforms::base::rename::Renamer for HygieneRenamer { + impl swc_core::ecma::transforms::base::rename::Renamer for HygieneRenamer<'_> { const MANGLE: bool = false; const RESET_N: bool = true; From b61de300e32f4cb29b7a2fce02f1ccc14013972b Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 14:44:17 +0200 Subject: [PATCH 54/59] Fix reexport cycle hanging --- .../src/references/esm/base.rs | 99 ++++++++++++++++++- ...c_a__ is a circular re-export__-8bbf47.txt | 9 ++ 2 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/issues/__l_Export __c_a__ is a circular re-export__-8bbf47.txt diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index 99037747405b3..e1f8d1e652f9d 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -147,6 +147,17 @@ impl ReferencedAsset { chunking_context: Vc>, export: Option, scope_hoisting_context: Option>, + ) -> Result> { + self.get_ident_inner(chunking_context, export, scope_hoisting_context, None) + .await + } + + async fn get_ident_inner( + &self, + chunking_context: Vc>, + export: Option, + scope_hoisting_context: Option>, + initial: Option<&ResolvedVc>>, ) -> Result> { Ok(match self { ReferencedAsset::Some(asset) => { @@ -160,8 +171,8 @@ impl ReferencedAsset { *asset.get_exports().await? { let exports = exports.expand_exports(None).await?; - let export = exports.exports.get(export); - match export { + let esm_export = exports.exports.get(export); + match esm_export { Some(EsmExport::LocalBinding(name, _)) => { // A local binding in a module that is merged in the same // group @@ -172,7 +183,7 @@ impl ReferencedAsset { } Some(b @ EsmExport::ImportedBinding(esm_ref, _, _)) | Some(b @ EsmExport::ImportedNamespace(esm_ref)) => { - let export = + let imported = if let EsmExport::ImportedBinding(_, export, _) = b { Some(export.clone()) } else { @@ -185,13 +196,30 @@ impl ReferencedAsset { ) .await?; + if let Some(&initial) = initial + && *referenced_asset == ReferencedAsset::Some(initial) + { + // `initial` reexports from `asset` reexports from + // `referenced_asset` (which is `initial`) + CircularReExport { + export: export.clone(), + import: imported.clone(), + module: *asset, + module_cycle: initial, + } + .resolved_cell() + .emit(); + return Ok(None); + } + // If the target module is still in the same group, we can // refer it locally, otherwise it will be imported return Ok( - match Box::pin(referenced_asset.get_ident( + match Box::pin(referenced_asset.get_ident_inner( chunking_context, - export, + imported, Some(scope_hoisting_context), + Some(asset), )) .await? { @@ -750,3 +778,64 @@ impl Issue for InvalidExport { Vc::cell(Some(self.source.clone())) } } + +#[turbo_tasks::value(shared)] +pub struct CircularReExport { + export: RcStr, + import: Option, + module: ResolvedVc>, + module_cycle: ResolvedVc>, + // TODO ideally we'd have an issue source here +} + +#[turbo_tasks::value_impl] +impl Issue for CircularReExport { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Error.into() + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok(StyledString::Line(vec![ + StyledString::Text("Export ".into()), + StyledString::Code(self.export.clone()), + StyledString::Text(" is a circular re-export".into()), + ]) + .cell()) + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Bindings.into() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.module.ident().path() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + Ok(Vc::cell(Some( + StyledString::Stack(vec![ + StyledString::Line(vec![StyledString::Text("The export".into())]), + StyledString::Line(vec![ + StyledString::Code(self.export.clone()), + StyledString::Text(" of module ".into()), + StyledString::Strong(self.module.ident().to_string().owned().await?), + ]), + StyledString::Line(vec![StyledString::Text( + "is a re-export of the export".into(), + )]), + StyledString::Line(vec![ + StyledString::Code(self.import.clone().unwrap_or_else(|| "*".into())), + StyledString::Text(" of module ".into()), + StyledString::Strong(self.module_cycle.ident().to_string().owned().await?), + StyledString::Text(".".into()), + ]), + ]) + .resolved_cell(), + ))) + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/issues/__l_Export __c_a__ is a circular re-export__-8bbf47.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/issues/__l_Export __c_a__ is a circular re-export__-8bbf47.txt new file mode 100644 index 0000000000000..2701a0e3ecc6e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/issues/__l_Export __c_a__ is a circular re-export__-8bbf47.txt @@ -0,0 +1,9 @@ +error - [bindings] [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/input/a.js Export a is a circular re-export + + The export + + a of module [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/input/a.js [test] (ecmascript) + + is a re-export of the export + + a of module [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/cycle/reexport-cycle/input/b.js [test] (ecmascript). \ No newline at end of file From fb24ca0084a062f9dda3118eb6fe46d94aba91ca Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 14:51:29 +0200 Subject: [PATCH 55/59] Change chunk item id to first entry instead --- turbopack/crates/turbopack-ecmascript/src/lib.rs | 9 ++++++--- .../crates/turbopack-ecmascript/src/merged_module.rs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index ea2562f11edb0..021790288d057 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -1210,7 +1210,7 @@ impl EcmascriptModuleContent { // TODO properly merge ASTs: // - somehow merge the SourceMap struct - let merged_ast = merge_modules(contents, entries, &merged_ctxts, &globals_merged).await?; + let merged_ast = merge_modules(contents, &entries, &merged_ctxts, &globals_merged).await?; let content = CodeGenResult { program: merged_ast, source_map: Arc::new(SourceMap::default()), @@ -1229,10 +1229,13 @@ impl EcmascriptModuleContent { extra_comments: SwcComments::default(), scope_hoisting_syntax_contexts: None, }; + let chunking_context = module_options.last().unwrap().await?.chunking_context; + let first_entry = entries.first().unwrap().0; let additional_ids = modules .keys() - .take(modules.len() - 1) + // Skip the first entry, which is the name of the chunk item + .filter(|m| **m != first_entry) .map(|m| m.chunk_item_id(*chunking_context).to_resolved()) .try_join() .await? @@ -1245,7 +1248,7 @@ impl EcmascriptModuleContent { #[allow(clippy::type_complexity)] async fn merge_modules( mut contents: Vec<(ResolvedVc>, CodeGenResult)>, - entries: Vec<(ResolvedVc>, usize)>, + entries: &Vec<(ResolvedVc>, usize)>, merged_ctxts: &'_ FxIndexMap>, SyntaxContext>, globals_merged: &'_ Globals, ) -> Result { diff --git a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs index 645a42c5f9dca..7d133cbc5fdb7 100644 --- a/turbopack/crates/turbopack-ecmascript/src/merged_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/merged_module.rs @@ -50,7 +50,7 @@ impl Module for MergedEcmascriptModule { fn ident(&self) -> Vc { // This purposely reuses the module's ident as it has replaced the original module, thus // there can never be a collision. - self.modules.last().unwrap().0.ident() + self.entries.first().unwrap().ident() } #[turbo_tasks::function] From 588e54e42ee12472987cf349f065e20086fc2e76 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:11:11 +0200 Subject: [PATCH 56/59] Review feedback: reverse map once --- turbopack/crates/turbopack-ecmascript/src/lib.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 021790288d057..d3c1c786a6904 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -1259,18 +1259,13 @@ async fn merge_modules( /// The syntax contexts in the merged AST (each module has its own) merged_ctxts: &'a FxIndexMap>, SyntaxContext>, /// The export syntax contexts in the current AST, which will be mapped to merged_ctxts - current_module_contexts: - &'a FxIndexMap>, SyntaxContext>, + reverse_module_contexts: + FxIndexMap>>, } impl VisitMut for SetSyntaxContextVisitor<'_> { fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { let module = if ctxt.has_mark(self.export_mark) { - *self - .current_module_contexts - .iter() - .find(|(_, module_ctxt)| *ctxt == **module_ctxt) - .unwrap() - .0 + *self.reverse_module_contexts.get(ctxt).unwrap() } else { self.current_module }; @@ -1293,7 +1288,10 @@ async fn merge_modules( current_module: *module, export_mark: *export_mark, merged_ctxts, - current_module_contexts: module_contexts, + reverse_module_contexts: module_contexts + .iter() + .map(|(m, ctxt)| (*ctxt, *m)) + .collect(), }); }); From 73d78157263620680ae725888c711f61a5b6e3f1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:29:56 +0200 Subject: [PATCH 57/59] Refactor ScopeHoistingContext --- .../turbopack-ecmascript/src/code_gen.rs | 2 +- .../crates/turbopack-ecmascript/src/lib.rs | 73 +++++++- .../src/references/async_module.rs | 5 +- .../src/references/esm/base.rs | 171 +++++++++--------- .../src/references/esm/binding.rs | 2 +- .../src/references/esm/export.rs | 20 +- .../src/side_effect_optimization/reference.rs | 4 +- 7 files changed, 158 insertions(+), 119 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/code_gen.rs b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs index 133db172bfbae..dbb8a0db4bbe0 100644 --- a/turbopack/crates/turbopack-ecmascript/src/code_gen.rs +++ b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs @@ -196,7 +196,7 @@ impl CodeGen { &self, g: Vc, ctx: Vc>, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, ) -> Result { match self { Self::AmdDefineWithDependenciesCodeGen(v) => v.code_generation(g, ctx).await, diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index d3c1c786a6904..85dd638fb1722 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -991,7 +991,7 @@ pub struct EcmascriptModuleContentOptions { impl EcmascriptModuleContentOptions { async fn merged_code_gens( &self, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, ) -> Result> { let EcmascriptModuleContentOptions { parsed, @@ -1378,13 +1378,63 @@ async fn merge_modules( // ident.sym = format!("{}$$${}{}", ident.sym, self.postfix, ident.ctxt.as_u32()).into(); // } // } + +/// Provides information about the other modules in the current scope hoisting group. #[derive(Clone, Copy)] -pub struct ScopeHoistingContext<'a> { - module: ResolvedVc>, - modules: &'a FxIndexMap>, bool>, - /// To import a specifier from another module, apply this context to the Ident - module_syntax_contexts: - &'a FxIndexMap>, SyntaxContext>, +pub enum ScopeHoistingContext<'a> { + Some { + /// The current module when scope hoisting + module: ResolvedVc>, + /// All modules in the current group, and whether they should expose their exports + modules: &'a FxIndexMap>, bool>, + /// To import a specifier from another module, apply this context to the Ident + module_syntax_contexts: + &'a FxIndexMap>, SyntaxContext>, + }, + None, +} + +impl<'a> ScopeHoistingContext<'a> { + /// The current module when scope hoisting + pub fn module(&self) -> Option>> { + match self { + ScopeHoistingContext::Some { module, .. } => Some(*module), + ScopeHoistingContext::None => None, + } + } + + /// Whether the current module should not expose it's exports into the module cache. + pub fn skip_module_exports(&self) -> bool { + match self { + ScopeHoistingContext::Some { + module, modules, .. + } => !(*modules.get(module).unwrap()), + ScopeHoistingContext::None => false, + } + } + + pub fn get_module_syntax_context( + &self, + module: ResolvedVc>, + ) -> Option { + match self { + ScopeHoistingContext::Some { + module_syntax_contexts, + .. + } => module_syntax_contexts.get(&module).copied(), + ScopeHoistingContext::None => None, + } + } + + pub fn get_module_index( + &self, + module: ResolvedVc>, + ) -> Option { + match self { + ScopeHoistingContext::Some { modules, .. } => modules.get_index_of(&module), + ScopeHoistingContext::None => None, + } + } } struct CodeGenResult { @@ -1443,12 +1493,12 @@ async fn process_parse_result( (is_export_mark, module_syntax_contexts) }); - let ctx = ScopeHoistingContext { + let ctx = ScopeHoistingContext::Some { module: scope_hoisting_options.module, modules: scope_hoisting_options.modules, module_syntax_contexts: &module_syntax_contexts, }; - let code_gens = options.unwrap().merged_code_gens(Some(ctx)).await?; + let code_gens = options.unwrap().merged_code_gens(ctx).await?; let preserved_exports = match &*scope_hoisting_options.module.get_exports().await? { EcmascriptExports::EsmExports(exports) => exports .await? @@ -1470,7 +1520,10 @@ async fn process_parse_result( Some((is_export_mark, module_syntax_contexts, preserved_exports)), ) } else if let Some(options) = options { - (options.merged_code_gens(None).await?, None) + ( + options.merged_code_gens(ScopeHoistingContext::None).await?, + None, + ) } else { (vec![], None) }; diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs index 1d9204e124ec2..66fc9b692c837 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -17,6 +17,7 @@ use turbopack_core::{ use super::esm::base::ReferencedAsset; use crate::{ + ScopeHoistingContext, code_gen::{CodeGeneration, CodeGenerationHoistedStmt}, utils::AstSyntaxContext, }; @@ -128,7 +129,7 @@ impl AsyncModule { ReferencedAsset::External(_, ExternalType::EcmaScriptModule) => { if self.import_externals { referenced_asset - .get_ident(chunking_context, None, None) + .get_ident(chunking_context, None, ScopeHoistingContext::None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) .map(|(i, ctx)| (i, ctx.unwrap_or_default().into())) @@ -142,7 +143,7 @@ impl AsyncModule { .contains(&ResolvedVc::upcast(*placeable)) { referenced_asset - .get_ident(chunking_context, None, None) + .get_ident(chunking_context, None, ScopeHoistingContext::None) .await? .map(|i| i.into_module_namespace_ident().unwrap()) .map(|(i, ctx)| (i, ctx.unwrap_or_default().into())) diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index e1f8d1e652f9d..cd1431a1208df 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -146,7 +146,7 @@ impl ReferencedAsset { &self, chunking_context: Vc>, export: Option, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, ) -> Result> { self.get_ident_inner(chunking_context, export, scope_hoisting_context, None) .await @@ -156,93 +156,88 @@ impl ReferencedAsset { &self, chunking_context: Vc>, export: Option, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, initial: Option<&ResolvedVc>>, ) -> Result> { Ok(match self { ReferencedAsset::Some(asset) => { - if let Some(scope_hoisting_context) = scope_hoisting_context { - if let Some(ctxt) = scope_hoisting_context - .module_syntax_contexts - .get(&ResolvedVc::upcast(*asset)) - { - if let Some(export) = &export { - if let EcmascriptExports::EsmExports(exports) = - *asset.get_exports().await? - { - let exports = exports.expand_exports(None).await?; - let esm_export = exports.exports.get(export); - match esm_export { - Some(EsmExport::LocalBinding(name, _)) => { - // A local binding in a module that is merged in the same - // group - return Ok(Some(ReferencedAssetIdent::LocalBinding { - ident: name.clone(), - ctxt: *ctxt, - })); + if let Some(ctxt) = + scope_hoisting_context.get_module_syntax_context(ResolvedVc::upcast(*asset)) + { + if let Some(export) = &export { + if let EcmascriptExports::EsmExports(exports) = *asset.get_exports().await? + { + let exports = exports.expand_exports(None).await?; + let esm_export = exports.exports.get(export); + match esm_export { + Some(EsmExport::LocalBinding(name, _)) => { + // A local binding in a module that is merged in the same + // group + return Ok(Some(ReferencedAssetIdent::LocalBinding { + ident: name.clone(), + ctxt, + })); + } + Some(b @ EsmExport::ImportedBinding(esm_ref, _, _)) + | Some(b @ EsmExport::ImportedNamespace(esm_ref)) => { + let imported = + if let EsmExport::ImportedBinding(_, export, _) = b { + Some(export.clone()) + } else { + None + }; + + let referenced_asset = ReferencedAsset::from_resolve_result( + esm_ref.resolve_reference(), + ) + .await?; + + if let Some(&initial) = initial + && *referenced_asset == ReferencedAsset::Some(initial) + { + // `initial` reexports from `asset` reexports from + // `referenced_asset` (which is `initial`) + CircularReExport { + export: export.clone(), + import: imported.clone(), + module: *asset, + module_cycle: initial, + } + .resolved_cell() + .emit(); + return Ok(None); } - Some(b @ EsmExport::ImportedBinding(esm_ref, _, _)) - | Some(b @ EsmExport::ImportedNamespace(esm_ref)) => { - let imported = - if let EsmExport::ImportedBinding(_, export, _) = b { - Some(export.clone()) - } else { - None - }; - - let referenced_asset = - ReferencedAsset::from_resolve_result( - esm_ref.resolve_reference(), - ) - .await?; - if let Some(&initial) = initial - && *referenced_asset == ReferencedAsset::Some(initial) + // If the target module is still in the same group, we can + // refer it locally, otherwise it will be imported + return Ok( + match Box::pin(referenced_asset.get_ident_inner( + chunking_context, + imported, + scope_hoisting_context, + Some(asset), + )) + .await? { - // `initial` reexports from `asset` reexports from - // `referenced_asset` (which is `initial`) - CircularReExport { - export: export.clone(), - import: imported.clone(), - module: *asset, - module_cycle: initial, - } - .resolved_cell() - .emit(); - return Ok(None); - } - - // If the target module is still in the same group, we can - // refer it locally, otherwise it will be imported - return Ok( - match Box::pin(referenced_asset.get_ident_inner( - chunking_context, - imported, - Some(scope_hoisting_context), - Some(asset), - )) - .await? - { - Some(ReferencedAssetIdent::Module { - namespace_ident, - // Overwrite the context. This import isn't - // inserted in the module that uses the import, - // but in the module containing the reexport - ctxt: None, - export, - }) => Some(ReferencedAssetIdent::Module { - namespace_ident, - ctxt: Some(*ctxt), - export, - }), - ident => ident, - }, - ); - } - Some(EsmExport::Error) | None => { - // Export not found, either there was already an error, or - // this is some dynamic (CJS) (re)export situation. - } + Some(ReferencedAssetIdent::Module { + namespace_ident, + // Overwrite the context. This import isn't + // inserted in the module that uses the import, + // but in the module containing the reexport + ctxt: None, + export, + }) => Some(ReferencedAssetIdent::Module { + namespace_ident, + ctxt: Some(ctxt), + export, + }), + ident => ident, + }, + ); + } + Some(EsmExport::Error) | None => { + // Export not found, either there was already an error, or + // this is some dynamic (CJS) (re)export situation. } } } @@ -502,7 +497,7 @@ impl EsmAssetReference { pub async fn code_generation( self: Vc, chunking_context: Vc>, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, ) -> Result { let this = &*self.await?; @@ -529,13 +524,11 @@ impl EsmAssetReference { _ => { let mut result = vec![]; - let merged_index = scope_hoisting_context - .zip(if let ReferencedAsset::Some(asset) = &*referenced_asset { - Some(*asset) - } else { - None - }) - .and_then(|(c, asset)| c.modules.get_index_of(&ResolvedVc::upcast(asset))); + let merged_index = if let ReferencedAsset::Some(asset) = &*referenced_asset { + scope_hoisting_context.get_module_index(*asset) + } else { + None + }; if let Some(merged_index) = merged_index { // Insert a placeholder to inline the merged module at the right place diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs index 733aec38ab9e0..1bcd84ff6e16a 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -43,7 +43,7 @@ impl EsmBinding { &self, _module_graph: Vc, chunking_context: Vc>, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, ) -> Result { let mut visitors = vec![]; diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 8222b11c5fb35..380143d1c10ff 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -557,11 +557,11 @@ impl EsmExports { pub async fn code_generation( self: Vc, chunking_context: Vc>, - scope_hoisting_context: Option>, + scope_hoisting_context: ScopeHoistingContext<'_>, parsed: Option>, export_usage_info: Option>, ) -> Result { - if scope_hoisting_context.is_some_and(|ctx| !*ctx.modules.get(&ctx.module).unwrap()) { + if scope_hoisting_context.skip_module_exports() { // If the current module is not exposed, no need to generate exports return Ok(CodeGeneration::empty()); } @@ -575,15 +575,10 @@ impl EsmExports { let mut dynamic_exports = Vec::>::new(); { - let id = if let Some(scope_hoisting_context) = scope_hoisting_context + let id = if let Some(module) = scope_hoisting_context.module() && !expanded.dynamic_exports.is_empty() { - Some( - scope_hoisting_context - .module - .chunk_item_id(Vc::upcast(chunking_context)) - .await?, - ) + Some(module.chunk_item_id(Vc::upcast(chunking_context)).await?) } else { None }; @@ -721,11 +716,8 @@ impl EsmExports { let early_hoisted_stmts = vec![CodeGenerationHoistedStmt::new( "__turbopack_esm__".into(), - if let Some(scope_hoisting_context) = scope_hoisting_context { - let id = scope_hoisting_context - .module - .chunk_item_id(Vc::upcast(chunking_context)) - .await?; + if let Some(module) = scope_hoisting_context.module() { + let id = module.chunk_item_id(Vc::upcast(chunking_context)).await?; quote!("$turbopack_esm($getters, $id);" as Stmt, turbopack_esm: Expr = TURBOPACK_ESM.into(), getters: Expr = getters, 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 c4601083d99bc..9ab4b2da26618 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -16,7 +16,7 @@ use super::{ facade::module::EcmascriptModuleFacadeModule, locals::module::EcmascriptModuleLocalsModule, }; use crate::{ - chunk::EcmascriptChunkPlaceable, code_gen::CodeGeneration, + ScopeHoistingContext, chunk::EcmascriptChunkPlaceable, code_gen::CodeGeneration, references::esm::base::ReferencedAsset, runtime_functions::TURBOPACK_IMPORT, utils::module_id_to_lit, }; @@ -142,7 +142,7 @@ impl EcmascriptModulePartReference { let referenced_asset = ReferencedAsset::from_resolve_result(self.resolve_reference()); let referenced_asset = referenced_asset.await?; let ident = referenced_asset - .get_ident(chunking_context, None, None) + .get_ident(chunking_context, None, ScopeHoistingContext::None) .await? .context("part module reference should have an ident")? .as_expr_individual(DUMMY_SP) From b6a5e07fceaf7187c9c1480c0d4ee246325219df Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:43:28 +0200 Subject: [PATCH 58/59] Clone globals only if necessary --- turbopack/crates/turbopack-ecmascript/src/lib.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 85dd638fb1722..048edf355a1df 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -1662,7 +1662,7 @@ async fn process_parse_result( .await } -/// Try to avoid cloning the AST and Globals by unwrapping the ReadRef. +/// Try to avoid cloning the AST and Globals by unwrapping the ReadRef (and cloning otherwise). async fn with_consumed_parse_result( parsed: ResolvedVc, success: impl AsyncFnOnce( @@ -1688,11 +1688,10 @@ async fn with_consumed_parse_result( }) => ( program.take(), &*source_map, - // TODO? - // Arc::get_mut(globals) - // .take() - // .map_or_else(|| globals.clone_data(), |v| std::mem::take(v)), - globals.clone_data(), + match Arc::try_unwrap(take(globals)) { + Ok(globals) => globals, + Err(globals) => globals.clone_data(), + }, &*eval_context, match Arc::try_unwrap(take(comments)) { Ok(comments) => Either::Left(comments), From c7386ecc2d217eb0cfb4373f64a7eabab0f21942 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:27:15 +0200 Subject: [PATCH 59/59] Emit correct comments for scope hoisted modules --- .../crates/turbopack-ecmascript/src/lib.rs | 262 ++++++++++++------ 1 file changed, 178 insertions(+), 84 deletions(-) diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs index 048edf355a1df..e754792910da6 100644 --- a/turbopack/crates/turbopack-ecmascript/src/lib.rs +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -58,7 +58,7 @@ use swc_core::{ atoms::Atom, base::SwcComments, common::{ - BytePos, DUMMY_SP, GLOBALS, Globals, Mark, SourceMap, SyntaxContext, + BytePos, DUMMY_SP, GLOBALS, Globals, Mark, SourceMap, Span, SyntaxContext, comments::{Comment, Comments}, util::take::Take, }, @@ -121,7 +121,7 @@ use crate::{ }, side_effect_optimization::reference::EcmascriptModulePartReference, simple_tree_shake::{ModuleExportUsageInfo, get_module_export_usages}, - swc_comments::ImmutableComments, + swc_comments::{CowComments, ImmutableComments}, transform::remove_shebang, }; @@ -1210,12 +1210,13 @@ impl EcmascriptModuleContent { // TODO properly merge ASTs: // - somehow merge the SourceMap struct - let merged_ast = merge_modules(contents, &entries, &merged_ctxts, &globals_merged).await?; + let (merged_ast, comments) = + merge_modules(contents, &entries, &merged_ctxts, &globals_merged).await?; let content = CodeGenResult { program: merged_ast, source_map: Arc::new(SourceMap::default()), + comments: CodeGenResultComments::ScopeHoisting { comments }, globals: Arc::new(globals_merged), - comments: Either::Left(Default::default()), is_esm: true, generate_source_map: false, original_source_map: None, @@ -1226,7 +1227,6 @@ impl EcmascriptModuleContent { .chunking_context .minify_type() .await?, - extra_comments: SwcComments::default(), scope_hoisting_syntax_contexts: None, }; @@ -1251,9 +1251,10 @@ async fn merge_modules( entries: &Vec<(ResolvedVc>, usize)>, merged_ctxts: &'_ FxIndexMap>, SyntaxContext>, globals_merged: &'_ Globals, -) -> Result { +) -> Result<(Program, Vec)> { struct SetSyntaxContextVisitor<'a> { current_module: ResolvedVc>, + current_module_idx: u32, /// A marker to quickly identify the special cross-module variable references export_mark: Mark, /// The syntax contexts in the merged AST (each module has its own) @@ -1262,6 +1263,7 @@ async fn merge_modules( reverse_module_contexts: FxIndexMap>>, } + impl VisitMut for SetSyntaxContextVisitor<'_> { fn visit_mut_syntax_context(&mut self, ctxt: &mut SyntaxContext) { let module = if ctxt.has_mark(self.export_mark) { @@ -1272,8 +1274,17 @@ async fn merge_modules( *ctxt = *self.merged_ctxts.get(&module).unwrap(); } + fn visit_mut_span(&mut self, span: &mut Span) { + span.lo = CodeGenResultComments::encode_bytepos(self.current_module_idx, span.lo); + span.hi = CodeGenResultComments::encode_bytepos(self.current_module_idx, span.hi); + } } + let comments = contents + .iter_mut() + .map(|(_, content)| content.comments.take()) + .collect::>(); + let prepare_module = |(module, content): &mut (ResolvedVc>, CodeGenResult)| { if let CodeGenResult { @@ -1286,6 +1297,7 @@ async fn merge_modules( GLOBALS.set(&*globals, || { content.visit_mut_with(&mut SetSyntaxContextVisitor { current_module: *module, + current_module_idx: module_contexts.get_index_of(module).unwrap() as u32, export_mark: *export_mark, merged_ctxts, reverse_module_contexts: module_contexts @@ -1367,7 +1379,7 @@ async fn merge_modules( // merged_ast.visit_mut_with(&mut DisplayContextVisitor { postfix: "merged" }); }); - Ok(merged_ast) + Ok((merged_ast, comments)) } // struct DisplayContextVisitor { @@ -1441,8 +1453,7 @@ struct CodeGenResult { program: Program, source_map: Arc, globals: Arc, - comments: Either>, - extra_comments: SwcComments, + comments: CodeGenResultComments, is_esm: bool, generate_source_map: bool, original_source_map: Option>>, @@ -1582,8 +1593,10 @@ async fn process_parse_result( program, source_map: source_map.clone(), globals: Arc::new(globals), - comments, - extra_comments, + comments: CodeGenResultComments::Single { + comments, + extra_comments, + }, is_esm, generate_source_map, original_source_map, @@ -1619,8 +1632,7 @@ async fn process_parse_result( }), source_map: Arc::new(SourceMap::default()), globals: Arc::new(Globals::default()), - comments: Either::Left(Default::default()), - extra_comments: Default::default(), + comments: CodeGenResultComments::Empty, is_esm: false, generate_source_map: false, original_source_map: None, @@ -1647,8 +1659,7 @@ async fn process_parse_result( }), source_map: Arc::new(SourceMap::default()), globals: Arc::new(Globals::default()), - comments: Either::Left(Default::default()), - extra_comments: Default::default(), + comments: CodeGenResultComments::Empty, is_esm: false, generate_source_map: false, original_source_map: None, @@ -1734,7 +1745,6 @@ async fn emit_content( program, source_map, comments, - extra_comments, is_esm, generate_source_map, original_source_map, @@ -1750,20 +1760,6 @@ async fn emit_content( let mut mappings = vec![]; { - let comments = match comments { - Either::Left(comments) => Either::Left(comments.into_consumable()), - Either::Right(ref comments) => Either::Right(comments.consumable()), - }; - let comments: &dyn Comments = match &comments { - Either::Left(comments) => comments, - Either::Right(comments) => comments, - }; - - let comments = MergedComments { - baseline: comments, - mutable: extra_comments, - }; - let mut wr = JsWriter::new( source_map.clone(), "\n", @@ -1774,6 +1770,8 @@ async fn emit_content( wr.set_indent_str(""); } + let comments = comments.consumable(); + let mut emitter = Emitter { cfg: swc_core::ecma::codegen::Config::default(), cm: source_map.clone(), @@ -1918,92 +1916,188 @@ fn hygiene_rename_only( ) } -struct MergedComments -where - A: Comments, - B: Comments, -{ - baseline: A, - mutable: B, +enum CodeGenResultComments { + Single { + comments: Either>, + extra_comments: SwcComments, + }, + ScopeHoisting { + comments: Vec, + }, + Empty, } -impl Comments for MergedComments -where - A: Comments, - B: Comments, -{ - fn add_leading(&self, pos: BytePos, cmt: Comment) { - self.mutable.add_leading(pos, cmt); +impl CodeGenResultComments { + fn take(&mut self) -> Self { + std::mem::replace(self, CodeGenResultComments::Empty) } - fn add_leading_comments(&self, pos: BytePos, comments: Vec) { - self.mutable.add_leading_comments(pos, comments); + fn consumable(&self) -> CodeGenResultCommentsConsumable { + match self { + CodeGenResultComments::Single { + comments, + extra_comments, + } => { + let x = match comments { + // TODO this shouldn't clone it + Either::Left(comments) => comments.consumable(), + Either::Right(comments) => comments.consumable(), + }; + CodeGenResultCommentsConsumable::Single { + comments: x, + extra_comments, + } + } + CodeGenResultComments::ScopeHoisting { comments } => { + CodeGenResultCommentsConsumable::ScopeHoisting { + comments: comments.iter().map(|c| c.consumable()).collect(), + } + } + CodeGenResultComments::Empty => CodeGenResultCommentsConsumable::Empty, + } + } + + fn encode_bytepos(module: u32, pos: BytePos) -> BytePos { + debug_assert!(module < 2u32.pow(SPAN_BITS_FOR_MODULE_ID)); + debug_assert!(pos.0 < 2u32.pow(SPAN_BITS_FOR_POS)); + BytePos((pos.0 & !(0b111111u32 << SPAN_BITS_FOR_POS)) | (module << SPAN_BITS_FOR_POS)) + } + fn decode_bytepos(pos: BytePos) -> (usize, BytePos) { + let module = pos.0 >> SPAN_BITS_FOR_POS; + let pos = BytePos(pos.0 & !(0b111111u32 << SPAN_BITS_FOR_POS)); + (module as usize, pos) + } +} +enum CodeGenResultCommentsConsumable<'a> { + Single { + comments: CowComments<'a>, + extra_comments: &'a SwcComments, + }, + ScopeHoisting { + comments: Vec>, + }, + Empty, +} + +unsafe impl Send for CodeGenResultComments {} +unsafe impl Sync for CodeGenResultComments {} + +const SPAN_BITS_FOR_MODULE_ID: u32 = 6; +const SPAN_BITS_FOR_POS: u32 = 32 - SPAN_BITS_FOR_MODULE_ID; +impl Comments for CodeGenResultCommentsConsumable<'_> { + fn add_leading(&self, _pos: BytePos, _cmt: Comment) { + unimplemented!() + } + + fn add_leading_comments(&self, _pos: BytePos, _comments: Vec) { + unimplemented!() } fn has_leading(&self, pos: BytePos) -> bool { - self.baseline.has_leading(pos) || self.mutable.has_leading(pos) + match self { + Self::Single { + comments, + extra_comments, + } => comments.has_leading(pos) || extra_comments.has_leading(pos), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].has_leading(pos) + } + Self::Empty => false, + } } - fn move_leading(&self, from: BytePos, to: BytePos) { - self.baseline.move_leading(from, to); - self.mutable.move_leading(from, to); + fn move_leading(&self, _from: BytePos, _to: BytePos) { + unimplemented!() } fn take_leading(&self, pos: BytePos) -> Option> { - let (v1, v2) = ( - self.baseline.take_leading(pos), - self.mutable.take_leading(pos), - ); - - merge_option_vec(v1, v2) + match self { + Self::Single { + comments, + extra_comments, + } => merge_option_vec(comments.take_leading(pos), extra_comments.take_leading(pos)), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].take_leading(pos) + } + Self::Empty => None, + } } fn get_leading(&self, pos: BytePos) -> Option> { - let (v1, v2) = ( - self.baseline.get_leading(pos), - self.mutable.get_leading(pos), - ); - - merge_option_vec(v1, v2) + match self { + Self::Single { + comments, + extra_comments, + } => merge_option_vec(comments.get_leading(pos), extra_comments.get_leading(pos)), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].get_leading(pos) + } + Self::Empty => None, + } } - fn add_trailing(&self, pos: BytePos, cmt: Comment) { - self.mutable.add_trailing(pos, cmt); + fn add_trailing(&self, _pos: BytePos, _cmt: Comment) { + unimplemented!() } - fn add_trailing_comments(&self, pos: BytePos, comments: Vec) { - self.mutable.add_trailing_comments(pos, comments); + fn add_trailing_comments(&self, _pos: BytePos, _comments: Vec) { + unimplemented!() } fn has_trailing(&self, pos: BytePos) -> bool { - self.baseline.has_trailing(pos) || self.mutable.has_trailing(pos) + match self { + Self::Single { + comments, + extra_comments, + } => comments.has_trailing(pos) || extra_comments.has_trailing(pos), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].has_trailing(pos) + } + Self::Empty => false, + } } - fn move_trailing(&self, from: BytePos, to: BytePos) { - self.baseline.move_trailing(from, to); - self.mutable.move_trailing(from, to); + fn move_trailing(&self, _from: BytePos, _to: BytePos) { + unimplemented!() } fn take_trailing(&self, pos: BytePos) -> Option> { - let (v1, v2) = ( - self.baseline.take_trailing(pos), - self.mutable.take_trailing(pos), - ); - - merge_option_vec(v1, v2) + match self { + Self::Single { + comments, + extra_comments, + } => merge_option_vec( + comments.take_trailing(pos), + extra_comments.take_trailing(pos), + ), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].take_trailing(pos) + } + Self::Empty => None, + } } fn get_trailing(&self, pos: BytePos) -> Option> { - let (v1, v2) = ( - self.baseline.get_trailing(pos), - self.mutable.get_trailing(pos), - ); - - merge_option_vec(v1, v2) + match self { + Self::Single { + comments, + extra_comments, + } => merge_option_vec(comments.get_leading(pos), extra_comments.get_leading(pos)), + Self::ScopeHoisting { comments } => { + let (module, pos) = CodeGenResultComments::decode_bytepos(pos); + comments[module].get_leading(pos) + } + Self::Empty => None, + } } - fn add_pure_comment(&self, pos: BytePos) { - self.mutable.add_pure_comment(pos); + fn add_pure_comment(&self, _pos: BytePos) { + unimplemented!() } }