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

backport: esm externals in turbopack #69590

Merged
merged 3 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/next-swc/crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,13 +846,13 @@ impl AppEndpoint {
{
entry_client_chunks.extend(chunks.await?.iter().copied());
}
for chunks in client_references_chunks_ref
for (chunks, _) in client_references_chunks_ref
.client_component_client_chunks
.values()
{
client_assets.extend(chunks.await?.iter().copied());
}
for chunks in client_references_chunks_ref
for (chunks, _) in client_references_chunks_ref
.client_component_ssr_chunks
.values()
{
Expand Down Expand Up @@ -929,7 +929,7 @@ impl AppEndpoint {
// initialization
let client_references_chunks = &*client_references_chunks.await?;

for &ssr_chunks in client_references_chunks
for (ssr_chunks, _) in client_references_chunks
.client_component_ssr_chunks
.values()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ fn client_modules_ssr_modifier() -> Vc<String> {

#[turbo_tasks::value]
pub struct ClientReferencesChunks {
pub client_component_client_chunks: IndexMap<ClientReferenceType, Vc<OutputAssets>>,
pub client_component_ssr_chunks: IndexMap<ClientReferenceType, Vc<OutputAssets>>,
pub client_component_client_chunks:
IndexMap<ClientReferenceType, (Vc<OutputAssets>, AvailabilityInfo)>,
pub client_component_ssr_chunks:
IndexMap<ClientReferenceType, (Vc<OutputAssets>, AvailabilityInfo)>,
pub layout_segment_client_chunks: IndexMap<Vc<NextServerComponentModule>, Vc<OutputAssets>>,
}

Expand Down Expand Up @@ -66,23 +68,47 @@ pub async fn get_app_client_references_chunks(
) => {
let ecmascript_client_reference_ref =
ecmascript_client_reference.await?;
(
client_chunking_context.root_chunk_group_assets(Vc::upcast(

let client_chunk_group = client_chunking_context
.root_chunk_group(Vc::upcast(
ecmascript_client_reference_ref.client_module,
)),
ssr_chunking_context.map(|ssr_chunking_context| {
ssr_chunking_context.root_chunk_group_assets(Vc::upcast(
ecmascript_client_reference_ref.ssr_module,
))
.await?;

(
(
client_chunk_group.assets,
client_chunk_group.availability_info,
),
if let Some(ssr_chunking_context) = ssr_chunking_context {
let ssr_chunk_group = ssr_chunking_context
.root_chunk_group(Vc::upcast(
ecmascript_client_reference_ref.ssr_module,
))
.await?;

Some((
ssr_chunk_group.assets,
ssr_chunk_group.availability_info,
))
}),
} else {
None
},
)
}
ClientReferenceType::CssClientReference(css_client_reference) => {
let css_client_reference_ref = css_client_reference.await?;
(
client_chunking_context.root_chunk_group_assets(Vc::upcast(
let client_chunk_group = client_chunking_context
.root_chunk_group(Vc::upcast(
css_client_reference_ref.client_module,
)),
))
.await?;

(
(
client_chunk_group.assets,
client_chunk_group.availability_info,
),
None,
)
}
Expand Down Expand Up @@ -165,6 +191,7 @@ pub async fn get_app_client_references_chunks(
})
.try_flat_join()
.await?;

let ssr_chunk_group = if !ssr_modules.is_empty() {
let ssr_entry_module = IncludeModulesModule::new(
base_ident.with_modifier(client_modules_ssr_modifier()),
Expand All @@ -184,6 +211,7 @@ pub async fn get_app_client_references_chunks(
} else {
None
};

let client_modules = client_reference_types
.iter()
.map(|client_reference_ty| async move {
Expand Down Expand Up @@ -240,8 +268,10 @@ pub async fn get_app_client_references_chunks(
if let ClientReferenceType::EcmascriptClientReference(_) =
client_reference_ty
{
client_component_client_chunks
.insert(client_reference_ty, client_chunks);
client_component_client_chunks.insert(
client_reference_ty,
(client_chunks, client_chunk_group.availability_info),
);
}
}
}
Expand All @@ -261,7 +291,10 @@ pub async fn get_app_client_references_chunks(
if let ClientReferenceType::EcmascriptClientReference(_) =
client_reference_ty
{
client_component_ssr_chunks.insert(client_reference_ty, ssr_chunks);
client_component_ssr_chunks.insert(
client_reference_ty,
(ssr_chunks, ssr_chunk_group.availability_info),
);
}
}
}
Expand Down
11 changes: 2 additions & 9 deletions packages/next-swc/crates/next-core/src/next_edge/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,8 @@ pub async fn get_edge_resolve_options_context(
.map(ToString::to_string),
);

match ty {
ServerContextType::AppRSC { .. } => custom_conditions.push("react-server".to_string()),
ServerContextType::AppRoute { .. }
| ServerContextType::Pages { .. }
| ServerContextType::PagesData { .. }
| ServerContextType::PagesApi { .. }
| ServerContextType::AppSSR { .. }
| ServerContextType::Middleware { .. }
| ServerContextType::Instrumentation { .. } => {}
if ty.supports_react_server() {
custom_conditions.push("react-server".to_string());
};

let resolve_options_context = ResolveOptionsContext {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/next-core/src/next_import_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ async fn rsc_aliases(
}

if runtime == NextRuntime::Edge {
if matches!(ty, ServerContextType::AppRSC { .. }) {
if ty.supports_react_server() {
alias["react"] = format!("next/dist/compiled/react{react_channel}/react.react-server");
alias["react-dom"] =
format!("next/dist/compiled/react-dom{react_channel}/react-dom.react-server");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use turbo_tasks_fs::{File, FileSystemPath};
use turbopack_binding::turbopack::{
core::{
asset::AssetContent,
chunk::{ChunkItemExt, ChunkableModule, ModuleId as TurbopackModuleId},
chunk::{
availability_info::AvailabilityInfo, ChunkItem, ChunkItemExt, ChunkableModule,
ModuleId as TurbopackModuleId,
},
output::OutputAsset,
virtual_output::VirtualOutputAsset,
},
Expand Down Expand Up @@ -66,61 +69,70 @@ impl ClientReferenceManifest {
.to_string()
.await?;

let client_module_id = ecmascript_client_reference
let client_chunk_item = ecmascript_client_reference
.client_module
.as_chunk_item(Vc::upcast(client_chunking_context))
.id()
.await?;
.as_chunk_item(Vc::upcast(client_chunking_context));

let client_module_id = client_chunk_item.id().await?;

let (client_chunks_paths, client_is_async) =
if let Some((client_chunks, client_availability_info)) =
client_references_chunks
.client_component_client_chunks
.get(&app_client_reference_ty)
{
let client_chunks = client_chunks.await?;
let client_chunks_paths = client_chunks
.iter()
.map(|chunk| chunk.ident().path())
.try_join()
.await?;

let chunk_paths = client_chunks_paths
.iter()
.filter_map(|chunk_path| client_relative_path.get_path_to(chunk_path))
.map(ToString::to_string)
// It's possible that a chunk also emits CSS files, that will
// be handled separatedly.
.filter(|path| path.ends_with(".js"))
// .map(RcStr::from) // BACKPORT: no RcStr
lubieowoce marked this conversation as resolved.
Show resolved Hide resolved
.collect::<Vec<_>>();

let is_async =
is_item_async(client_availability_info, client_chunk_item).await?;

(chunk_paths, is_async)
} else {
(Vec::new(), false)
};

let client_chunks_paths = if let Some(client_chunks) = client_references_chunks
.client_component_client_chunks
.get(&app_client_reference_ty)
{
let client_chunks = client_chunks.await?;
let client_chunks_paths = client_chunks
.iter()
.map(|chunk| chunk.ident().path())
.try_join()
.await?;

client_chunks_paths
.iter()
.filter_map(|chunk_path| client_relative_path.get_path_to(chunk_path))
.map(ToString::to_string)
// It's possible that a chunk also emits CSS files, that will
// be handled separatedly.
.filter(|path| path.ends_with(".js"))
.collect::<Vec<_>>()
} else {
Vec::new()
};
entry_manifest.client_modules.module_exports.insert(
get_client_reference_module_key(&server_path, "*"),
ManifestNodeEntry {
name: "*".to_string(),
id: (&*client_module_id).into(),
chunks: client_chunks_paths,
// TODO(WEB-434)
r#async: false,
r#async: client_is_async,
},
);

if let Some(ssr_chunking_context) = ssr_chunking_context {
let ssr_module_id = ecmascript_client_reference
let ssr_chunk_item = ecmascript_client_reference
.ssr_module
.as_chunk_item(Vc::upcast(ssr_chunking_context))
.id()
.await?;
.as_chunk_item(Vc::upcast(ssr_chunking_context));

let ssr_chunks_paths = if runtime == NextRuntime::Edge {
let ssr_module_id = ssr_chunk_item.id().await?;

let (ssr_chunks_paths, ssr_is_async) = if runtime == NextRuntime::Edge {
// the chunks get added to the middleware-manifest.json instead
// of this file because the
// edge runtime doesn't support dynamically
// loading chunks.
Vec::new()
} else if let Some(ssr_chunks) = client_references_chunks
.client_component_ssr_chunks
.get(&app_client_reference_ty)
(Vec::new(), false)
} else if let Some((ssr_chunks, ssr_availability_info)) =
client_references_chunks
.client_component_ssr_chunks
.get(&app_client_reference_ty)
{
let ssr_chunks = ssr_chunks.await?;

Expand All @@ -130,23 +142,28 @@ impl ClientReferenceManifest {
.try_join()
.await?;

ssr_chunks_paths
let chunk_paths = ssr_chunks_paths
.iter()
.filter_map(|chunk_path| node_root_ref.get_path_to(chunk_path))
.map(ToString::to_string)
.collect::<Vec<_>>()
// .map(RcStr::from) // BACKPORT: no RcStr
lubieowoce marked this conversation as resolved.
Show resolved Hide resolved
.collect::<Vec<_>>();

let is_async = is_item_async(ssr_availability_info, ssr_chunk_item).await?;

(chunk_paths, is_async)
} else {
Vec::new()
(Vec::new(), false)
};

let mut ssr_manifest_node = ManifestNode::default();
ssr_manifest_node.module_exports.insert(
"*".to_string(),
ManifestNodeEntry {
name: "*".to_string(),
id: (&*ssr_module_id).into(),
chunks: ssr_chunks_paths,
// TODO(WEB-434)
r#async: false,
r#async: ssr_is_async,
},
);

Expand Down Expand Up @@ -250,3 +267,18 @@ pub fn get_client_reference_module_key(server_path: &str, export_name: &str) ->
format!("{}#{}", server_path, export_name)
}
}

async fn is_item_async(
availability_info: &AvailabilityInfo,
chunk_item: Vc<Box<dyn ChunkItem>>,
) -> Result<bool> {
let Some(available_chunk_items) = availability_info.available_chunk_items() else {
return Ok(false);
};

let Some(info) = &*available_chunk_items.get(chunk_item).await? else {
return Ok(false);
};

Ok(info.is_async)
}
Loading
Loading