Skip to content
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
4 changes: 0 additions & 4 deletions crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1566,8 +1566,6 @@ impl AppEndpoint {

if emit_manifests == EmitManifests::Full {
let dynamic_import_entries = collect_next_dynamic_chunks(
*module_graphs.full,
*client_chunking_context,
next_dynamic_imports,
NextDynamicChunkAvailability::ClientReferences(
&*(client_references_chunks.await?),
Expand Down Expand Up @@ -1682,8 +1680,6 @@ impl AppEndpoint {
let loadable_manifest_output = if emit_manifests == EmitManifests::Full {
// create react-loadable-manifest for next/dynamic
let dynamic_import_entries = collect_next_dynamic_chunks(
*module_graphs.full,
*client_chunking_context,
next_dynamic_imports,
NextDynamicChunkAvailability::ClientReferences(
&*(client_references_chunks.await?),
Expand Down
57 changes: 35 additions & 22 deletions crates/next-api/src/dynamic_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,29 @@ use turbo_tasks::{
debug::ValueDebugFormat, trace::TraceRawVcs,
};
use turbopack_core::{
chunk::{ChunkableModule, ChunkingContext, availability_info::AvailabilityInfo},
chunk::{ChunkGroupResult, ChunkableModule},
module::Module,
module_graph::{ModuleGraph, ModuleGraphLayer},
module_graph::ModuleGraphLayer,
output::{OutputAssetsReference, OutputAssetsWithReferenced},
};

use crate::module_graph::DynamicImportEntriesWithImporter;

pub(crate) enum NextDynamicChunkAvailability<'a> {
/// In App Router, the client references
/// In App Router, the client references chunks contain the async loaders
ClientReferences(&'a ClientReferencesChunks),
/// In Pages Router, the base page chunk group
AvailabilityInfo(AvailabilityInfo),
/// In Pages Router, the base page chunk group result
PageChunkGroup(&'a ChunkGroupResult),
}

/// Collects the chunk outputs for next/dynamic imports by looking up pre-computed
/// async loaders from the chunk group results.
///
/// This function no longer recomputes chunks - instead it looks up the async loader
/// outputs that were already computed by `make_chunk_group` when the parent chunk
/// groups were created. This ensures consistency between the manifest and the actual
/// chunks served at runtime.
pub(crate) async fn collect_next_dynamic_chunks(
module_graph: Vc<ModuleGraph>,
chunking_context: Vc<Box<dyn ChunkingContext>>,
dynamic_import_entries: ReadRef<DynamicImportEntriesWithImporter>,
chunking_availability: NextDynamicChunkAvailability<'_>,
) -> Result<ResolvedVc<DynamicImportedChunks>> {
Expand All @@ -57,28 +62,36 @@ pub(crate) async fn collect_next_dynamic_chunks(
.map(|(dynamic_entry, parent_client_reference)| async move {
let module = ResolvedVc::upcast::<Box<dyn ChunkableModule>>(*dynamic_entry);

// This is the availability info for the parent chunk group, i.e. the client reference
// containing the next/dynamic imports
let availability_info = match chunking_availability {
// Look up the pre-computed async loader from the parent chunk group
let async_loader = match chunking_availability {
NextDynamicChunkAvailability::ClientReferences(client_reference_chunks) => {
client_reference_chunks
// For App Router: look up the chunk group for the parent client reference,
// then find the async loader for this dynamic entry
let parent_ref = parent_client_reference
.context("Parent client reference not found for next/dynamic import")?;
let chunk_group = client_reference_chunks
.client_component_client_chunks
.get(
&parent_client_reference.context(
"Parent client reference not found for next/dynamic import",
)?,
)
.get(&parent_ref)
.context("Client reference chunk group not found for next/dynamic import")?
.await?
.availability_info
.await?;
// Copy the ResolvedVc out of the map to avoid lifetime issues
*chunk_group.async_loaders_by_module.get(&module).context(
"Dynamic entry not found in async loaders - this may indicate the dynamic \
import is not reachable from the client reference",
)?
}
NextDynamicChunkAvailability::AvailabilityInfo(availability_info) => {
*availability_info
NextDynamicChunkAvailability::PageChunkGroup(chunk_group) => {
// For Pages Router: look up directly in the page's chunk group
// Copy the ResolvedVc out of the map to avoid lifetime issues
*chunk_group.async_loaders_by_module.get(&module).context(
"Dynamic entry not found in async loaders - this may indicate the dynamic \
import is not reachable from the page entry",
)?
}
};

let async_loader =
chunking_context.async_loader_chunk_item(*module, module_graph, availability_info);
// Get the output assets from the async loader reference
// Upcast to OutputAssetsReference to call references()
let async_chunk_group = async_loader.references().to_resolved().await?;

Ok((*dynamic_entry, (*dynamic_entry, async_chunk_group)))
Expand Down
29 changes: 12 additions & 17 deletions crates/next-api/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ impl PageEndpoint {
let ssr_module_graph = self.ssr_module_graph();

let next_dynamic_imports = if let PageEndpointType::Html = this.ty {
let client_availability_info = self.client_chunk_group().await?.availability_info;
let client_chunk_group = self.client_chunk_group().await?;

let client_module_graph = self.client_module_graph();
let per_page_module_graph = *project.per_page_module_graph().await?;
Expand Down Expand Up @@ -966,26 +966,21 @@ impl PageEndpoint {
NextDynamicGraphs::new(client_module_graph, per_page_module_graph)
.get_next_dynamic_imports_for_endpoint(self.client_module())
.await?;
Some((next_dynamic_imports, client_availability_info))
Some((next_dynamic_imports, client_chunk_group))
} else {
None
};

let dynamic_import_entries = if let Some((
next_dynamic_imports,
client_availability_info,
)) = next_dynamic_imports
{
collect_next_dynamic_chunks(
self.client_module_graph(),
project.client_chunking_context(),
next_dynamic_imports,
NextDynamicChunkAvailability::AvailabilityInfo(client_availability_info),
)
.await?
} else {
DynamicImportedChunks::default().resolved_cell()
};
let dynamic_import_entries =
if let Some((next_dynamic_imports, client_chunk_group)) = next_dynamic_imports {
collect_next_dynamic_chunks(
next_dynamic_imports,
NextDynamicChunkAvailability::PageChunkGroup(&client_chunk_group),
)
.await?
} else {
DynamicImportedChunks::default().resolved_cell()
};

let chunking_context: Vc<Box<dyn ChunkingContext>> = match runtime {
NextRuntime::NodeJs => Vc::upcast(node_chunking_context),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ pub async fn get_app_client_references_chunks(
let mut current_client_chunk_group = ChunkGroupResult {
assets: ResolvedVc::cell(vec![]),
referenced_assets: ResolvedVc::cell(vec![]),
references: ResolvedVc::cell(vec![]),
availability_info: client_availability_info,
async_loaders_by_module: FxIndexMap::default(),
}
.resolved_cell();
let mut current_ssr_chunk_group = ChunkGroupResult::empty_resolved();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use turbo_rcstr::{RcStr, rcstr};
use turbo_tasks::{IntoTraitRef, ResolvedVc, ValueToString, Vc};
use turbo_tasks_fs::{File, FileContent};
use turbopack_core::{
asset::{Asset, AssetContent},
asset::AssetContent,
chunk::{
AsyncModuleInfo, ChunkGroupType, ChunkItem, ChunkType, ChunkableModule,
ChunkableModuleReference, ChunkingContext, ChunkingType, ChunkingTypeOption,
Expand Down Expand Up @@ -249,18 +249,6 @@ impl Module for EcmascriptClientReferenceModule {
}
}

#[turbo_tasks::value_impl]
impl Asset for EcmascriptClientReferenceModule {
#[turbo_tasks::function]
fn content(&self) -> Vc<AssetContent> {
AssetContent::File(
FileContent::Content("// This is a proxy module for Next.js client references.".into())
.resolved_cell(),
)
.cell()
}
}

#[turbo_tasks::value_impl]
impl ChunkableModule for EcmascriptClientReferenceModule {
#[turbo_tasks::function]
Expand Down
14 changes: 0 additions & 14 deletions crates/next-core/src/next_dynamic/dynamic_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use anyhow::Result;
use indoc::formatdoc;
use turbo_rcstr::{RcStr, rcstr};
use turbo_tasks::{ResolvedVc, Vc};
use turbo_tasks_fs::FileContent;
use turbopack_core::{
asset::{Asset, AssetContent},
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
ident::AssetIdent,
module::{Module, ModuleSideEffects},
Expand Down Expand Up @@ -78,18 +76,6 @@ impl Module for NextDynamicEntryModule {
}
}

#[turbo_tasks::value_impl]
impl Asset for NextDynamicEntryModule {
#[turbo_tasks::function]
fn content(&self) -> Vc<AssetContent> {
AssetContent::File(
FileContent::Content("// This is a marker module for Next.js dynamic.".into())
.resolved_cell(),
)
.cell()
}
}

#[turbo_tasks::value_impl]
impl ChunkableModule for NextDynamicEntryModule {
#[turbo_tasks::function]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use anyhow::Result;
use indoc::formatdoc;
use turbo_rcstr::rcstr;
use turbo_tasks::{ResolvedVc, Vc};
use turbo_tasks_fs::{FileContent, FileSystemPath};
use turbo_tasks_fs::FileSystemPath;
use turbopack_core::{
asset::{Asset, AssetContent},
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
ident::AssetIdent,
module::{Module, ModuleSideEffects},
Expand Down Expand Up @@ -94,20 +93,6 @@ impl Module for NextServerComponentModule {
}
}

#[turbo_tasks::value_impl]
impl Asset for NextServerComponentModule {
#[turbo_tasks::function]
fn content(&self) -> Vc<AssetContent> {
AssetContent::File(
FileContent::Content(
"// This is a marker module for Next.js server components.".into(),
)
.resolved_cell(),
)
.cell()
}
}

#[turbo_tasks::value_impl]
impl ChunkableModule for NextServerComponentModule {
#[turbo_tasks::function]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use anyhow::Result;
use indoc::formatdoc;
use turbo_rcstr::rcstr;
use turbo_tasks::{ResolvedVc, Vc};
use turbo_tasks_fs::{FileContent, FileSystemPath};
use turbo_tasks_fs::FileSystemPath;
use turbopack_core::{
asset::{Asset, AssetContent},
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext, ModuleChunkItemIdExt},
ident::AssetIdent,
module::{Module, ModuleSideEffects},
Expand Down Expand Up @@ -75,18 +74,6 @@ impl Module for NextServerUtilityModule {
}
}

#[turbo_tasks::value_impl]
impl Asset for NextServerUtilityModule {
#[turbo_tasks::function]
fn content(&self) -> Vc<AssetContent> {
AssetContent::File(
FileContent::Content("// This is a marker module for Next.js server utilities.".into())
.resolved_cell(),
)
.cell()
}
}

#[turbo_tasks::value_impl]
impl ChunkableModule for NextServerUtilityModule {
#[turbo_tasks::function]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ pub async fn get_swc_ecma_transform_rule_impl(
enable_mdx_rs: bool,
) -> Result<Option<ModuleRule>> {
use anyhow::bail;
use turbo_tasks::TryFlatJoinIterExt;
use turbo_tasks::{TryFlatJoinIterExt, ValueToString};
use turbo_tasks_fs::FileContent;
use turbopack_core::{
asset::Asset,
module::Module,
reference_type::{CommonJsReferenceSubType, ReferenceType},
resolve::{handle_resolve_error, parse::Request, resolve},
};
Expand Down Expand Up @@ -133,7 +134,16 @@ pub async fn get_swc_ecma_transform_rule_impl(
return Ok(None);
};

let content = &*plugin_module.content().file_content().await?;
let Some(plugin_source) = &*plugin_module.source().await? else {
use anyhow::bail;

bail!(
"Expected source for plugin module: {}",
plugin_module.ident().to_string().await?
);
};

let content = &*plugin_source.content().file_content().await?;
let FileContent::Content(file) = content else {
bail!("Expected file content for plugin module");
};
Expand Down
10 changes: 1 addition & 9 deletions crates/next-core/src/raw_ecmascript_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use turbo_tasks::{FxIndexMap, FxIndexSet, ResolvedVc, TryJoinIterExt, ValueToStr
use turbo_tasks_fs::{FileContent, rope::Rope};
use turbopack::{ModuleAssetContext, module_options::CustomModuleType};
use turbopack_core::{
asset::{Asset, AssetContent},
asset::Asset,
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext},
code_builder::CodeBuilder,
compile_time_info::{
Expand Down Expand Up @@ -103,14 +103,6 @@ impl Module for RawEcmascriptModule {
}
}

#[turbo_tasks::value_impl]
impl Asset for RawEcmascriptModule {
#[turbo_tasks::function]
fn content(&self) -> Vc<AssetContent> {
self.source.content()
}
}

#[turbo_tasks::value_impl]
impl ChunkableModule for RawEcmascriptModule {
#[turbo_tasks::function]
Expand Down
Loading
Loading