Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(turbopack): Use correct SyntaxContext for __turbopack_esm__ #73544

Draft
wants to merge 10 commits into
base: canary
Choose a base branch
from
2 changes: 2 additions & 0 deletions turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ pub(crate) struct ImportMap {
/// The module specifiers of star imports that are accessed dynamically and should be imported
/// as a whole.
full_star_imports: FxHashSet<Atom>,

pub(crate) exports: FxHashMap<RcStr, Id>,
}

/// Represents a collection of [webpack-style "magic comments"][magic] that override import
Expand Down
2 changes: 1 addition & 1 deletion turbopack/crates/turbopack-ecmascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ impl EcmascriptModuleContent {
if let EcmascriptExports::EsmExports(exports) = *exports.await? {
Some(
exports
.code_generation(module_graph, chunking_context)
.code_generation(module_graph, chunking_context, *parsed)
.await?,
)
} else {
Expand Down
24 changes: 16 additions & 8 deletions turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{borrow::Cow, collections::BTreeMap, ops::ControlFlow};

use anyhow::Result;
use anyhow::{Context, Result};
use rustc_hash::FxHashSet;
use serde::{Deserialize, Serialize};
use swc_core::{
Expand Down Expand Up @@ -31,6 +31,7 @@ use crate::{
chunk::{EcmascriptChunkPlaceable, EcmascriptExports},
code_gen::{CodeGeneration, CodeGenerationHoistedStmt},
magic_identifier,
parse::ParseResult,
runtime_functions::{TURBOPACK_DYNAMIC, TURBOPACK_ESM},
};

Expand Down Expand Up @@ -494,8 +495,12 @@ impl EsmExports {
self: Vc<Self>,
_module_graph: Vc<ModuleGraph>,
chunking_context: Vc<Box<dyn ChunkingContext>>,
parsed: Vc<ParseResult>,
) -> Result<CodeGeneration> {
let expanded = self.expand_exports().await?;
let ParseResult::Ok { eval_context, .. } = &*parsed.await? else {
anyhow::bail!("failed to get eval context");
};

let mut dynamic_exports = Vec::<Box<Expr>>::new();
for dynamic_export_asset in &expanded.dynamic_exports {
Expand All @@ -522,20 +527,23 @@ impl EsmExports {
} else {
Cow::Borrowed(name.as_str())
};
let ctxt = eval_context
.imports
.exports
.get(name)
.map(|id| id.1)
.context("failed to get the correct SyntaxContext")?;

if *mutable {
Some(quote!(
"([() => $local, ($new) => $local = $new])" as Expr,
local = Ident::new(local.into(), DUMMY_SP, Default::default()),
new = Ident::new(
format!("new_{name}").into(),
DUMMY_SP,
Default::default()
),
local = Ident::new(local.into(), DUMMY_SP, ctxt),
new = Ident::new(format!("new_{name}").into(), DUMMY_SP, ctxt),
))
} else {
Some(quote!(
"(() => $local)" as Expr,
local = Ident::new((name as &str).into(), DUMMY_SP, Default::default())
local = Ident::new((name as &str).into(), DUMMY_SP, ctxt)
))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ use crate::{
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions,
EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports,
},
parse::ParseResult,
process_content_with_code_gens,
};

/// The chunk item for [EcmascriptModuleFacadeModule].
#[turbo_tasks::value(shared)]
pub struct EcmascriptModuleFacadeChunkItem {
pub(crate) module: ResolvedVc<EcmascriptModuleFacadeModule>,
pub(crate) parsed: ResolvedVc<ParseResult>,
pub(crate) module_graph: ResolvedVc<ModuleGraph>,
pub(crate) chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
}
Expand Down Expand Up @@ -68,7 +70,7 @@ impl EcmascriptChunkItem for EcmascriptModuleFacadeChunkItem {

let esm_code_gens = self
.module
.code_generation(*self.module_graph, *chunking_context)
.code_generation(*self.module_graph, *chunking_context, *self.parsed)
.await?;
let additional_code_gens = [
self.module
Expand All @@ -80,7 +82,7 @@ impl EcmascriptChunkItem for EcmascriptModuleFacadeChunkItem {
)
.await?,
exports
.code_generation(*self.module_graph, *chunking_context)
.code_generation(*self.module_graph, *chunking_context, *self.parsed)
.await?,
];
let code_gens = esm_code_gens.iter().chain(additional_code_gens.iter());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use super::chunk_item::EcmascriptModuleFacadeChunkItem;
use crate::{
chunk::{EcmascriptChunkPlaceable, EcmascriptExports},
code_gen::CodeGeneration,
parse::ParseResult,
references::{
async_module::{AsyncModule, OptionAsyncModule},
esm::{EsmExport, EsmExports},
Expand All @@ -31,14 +32,19 @@ use crate::{
#[turbo_tasks::value]
pub struct EcmascriptModuleFacadeModule {
pub module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
pub parsed: ResolvedVc<ParseResult>,
pub ty: ModulePart,
}

#[turbo_tasks::value_impl]
impl EcmascriptModuleFacadeModule {
#[turbo_tasks::function]
pub fn new(module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>, ty: ModulePart) -> Vc<Self> {
EcmascriptModuleFacadeModule { module, ty }.cell()
pub fn new(
module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
parsed: ResolvedVc<ParseResult>,
ty: ModulePart,
) -> Vc<Self> {
EcmascriptModuleFacadeModule { module, parsed, ty }.cell()
}

#[turbo_tasks::function]
Expand All @@ -65,6 +71,7 @@ impl EcmascriptModuleFacadeModule {
self: Vc<Self>,
module_graph: Vc<ModuleGraph>,
chunking_context: Vc<Box<dyn ChunkingContext>>,
parsed: Vc<ParseResult>,
) -> Result<Vec<CodeGeneration>> {
let this = self.await?;
Ok(match &this.ty {
Expand All @@ -86,9 +93,13 @@ impl EcmascriptModuleFacadeModule {
.try_join()
.await?;
code_gens.push(
EcmascriptModulePartReference::new_part(*this.module, ModulePart::locals())
.code_generation(module_graph, chunking_context)
.await?,
EcmascriptModulePartReference::new_part(
*this.module,
parsed,
ModulePart::locals(),
)
.code_generation(module_graph, chunking_context)
.await?,
);
code_gens
}
Expand All @@ -110,29 +121,41 @@ impl EcmascriptModuleFacadeModule {
.try_join()
.await?;
code_gens.push(
EcmascriptModulePartReference::new_part(*this.module, ModulePart::locals())
.code_generation(module_graph, chunking_context)
.await?,
EcmascriptModulePartReference::new_part(
*this.module,
parsed,
ModulePart::locals(),
)
.code_generation(module_graph, chunking_context)
.await?,
);
code_gens
}
ModulePart::Facade => {
vec![
EcmascriptModulePartReference::new_part(*this.module, ModulePart::evaluation())
.code_generation(module_graph, chunking_context)
.await?,
EcmascriptModulePartReference::new_part(*this.module, ModulePart::exports())
.code_generation(module_graph, chunking_context)
.await?,
EcmascriptModulePartReference::new_part(
*this.module,
parsed,
ModulePart::evaluation(),
)
.code_generation(module_graph, chunking_context)
.await?,
EcmascriptModulePartReference::new_part(
*this.module,
parsed,
ModulePart::exports(),
)
.code_generation(module_graph, chunking_context)
.await?,
]
}
ModulePart::RenamedNamespace { .. } => vec![
EcmascriptModulePartReference::new(*this.module)
EcmascriptModulePartReference::new(*this.module, parsed)
.code_generation(module_graph, chunking_context)
.await?,
],
ModulePart::RenamedExport { .. } => vec![
EcmascriptModulePartReference::new(*this.module)
EcmascriptModulePartReference::new(*this.module, parsed)
.code_generation(module_graph, chunking_context)
.await?,
],
Expand Down Expand Up @@ -171,9 +194,13 @@ impl Module for EcmascriptModuleFacadeModule {
.iter()
.map(|r| ResolvedVc::upcast(*r))
.chain(std::iter::once(ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(*self.module, ModulePart::locals())
.to_resolved()
.await?,
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::locals(),
)
.to_resolved()
.await?,
)))
.collect()
}
Expand All @@ -193,9 +220,13 @@ impl Module for EcmascriptModuleFacadeModule {
.iter()
.map(|r| ResolvedVc::upcast(*r))
.chain(std::iter::once(ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(*self.module, ModulePart::locals())
.to_resolved()
.await?,
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::locals(),
)
.to_resolved()
.await?,
)))
.collect()
}
Expand All @@ -204,6 +235,7 @@ impl Module for EcmascriptModuleFacadeModule {
ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::evaluation(),
)
.to_resolved()
Expand All @@ -212,6 +244,7 @@ impl Module for EcmascriptModuleFacadeModule {
ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::exports(),
)
.to_resolved()
Expand All @@ -221,14 +254,14 @@ impl Module for EcmascriptModuleFacadeModule {
}
ModulePart::RenamedNamespace { .. } => {
vec![ResolvedVc::upcast(
EcmascriptModulePartReference::new(*self.module)
EcmascriptModulePartReference::new(*self.module, *self.parsed)
.to_resolved()
.await?,
)]
}
ModulePart::RenamedExport { .. } => {
vec![ResolvedVc::upcast(
EcmascriptModulePartReference::new(*self.module)
EcmascriptModulePartReference::new(*self.module, *self.parsed)
.to_resolved()
.await?,
)]
Expand Down Expand Up @@ -290,6 +323,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::locals(),
)
.to_resolved()
Expand Down Expand Up @@ -337,6 +371,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::exports(),
)
.to_resolved()
Expand All @@ -348,9 +383,13 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
);
}
star_exports.push(ResolvedVc::upcast(
EcmascriptModulePartReference::new_part(*self.module, ModulePart::exports())
.to_resolved()
.await?,
EcmascriptModulePartReference::new_part(
*self.module,
*self.parsed,
ModulePart::exports(),
)
.to_resolved()
.await?,
));
}
ModulePart::RenamedExport {
Expand All @@ -361,7 +400,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
export.clone(),
EsmExport::ImportedBinding(
ResolvedVc::upcast(
EcmascriptModulePartReference::new(*self.module)
EcmascriptModulePartReference::new(*self.module, *self.parsed)
.to_resolved()
.await?,
),
Expand All @@ -374,7 +413,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
exports.insert(
export.clone(),
EsmExport::ImportedNamespace(ResolvedVc::upcast(
EcmascriptModulePartReference::new(*self.module)
EcmascriptModulePartReference::new(*self.module, *self.parsed)
.to_resolved()
.await?,
)),
Expand Down Expand Up @@ -419,19 +458,22 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule {
#[turbo_tasks::value_impl]
impl ChunkableModule for EcmascriptModuleFacadeModule {
#[turbo_tasks::function]
fn as_chunk_item(
async fn as_chunk_item(
self: ResolvedVc<Self>,
module_graph: ResolvedVc<ModuleGraph>,
chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
Vc::upcast(
) -> Result<Vc<Box<dyn turbopack_core::chunk::ChunkItem>>> {
let this = self.await?;

Ok(Vc::upcast(
EcmascriptModuleFacadeChunkItem {
module: self,
parsed: this.parsed,
module_graph,
chunking_context,
}
.cell(),
)
))
}
}

Expand Down
Loading
Loading