Skip to content

Commit

Permalink
chunk_group retuns ChunkGroupResults
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jan 12, 2024
1 parent a5df475 commit e3ad207
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 108 deletions.
41 changes: 31 additions & 10 deletions crates/turbopack-build/src/chunking_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ use turbopack_core::{
chunk::{
availability_info::AvailabilityInfo,
chunk_group::{make_chunk_group, MakeChunkGroupResult},
Chunk, ChunkItem, ChunkableModule, ChunkingContext, EvaluatableAssets, ModuleId,
Chunk, ChunkGroupResult, ChunkItem, ChunkableModule, ChunkingContext, EvaluatableAssets,
ModuleId,
},
environment::Environment,
ident::AssetIdent,
module::Module,
output::{OutputAsset, OutputAssets},
output::OutputAsset,
};
use turbopack_ecmascript::{
chunk::{EcmascriptChunk, EcmascriptChunkPlaceable, EcmascriptChunkingContext},
Expand Down Expand Up @@ -141,6 +142,12 @@ impl BuildChunkingContext {
}
}

#[turbo_tasks::value]
pub struct EntryChunkGroupResult {
pub asset: Vc<Box<dyn OutputAsset>>,
pub availability_info: AvailabilityInfo,
}

#[turbo_tasks::value_impl]
impl BuildChunkingContext {
#[turbo_tasks::function]
Expand All @@ -164,10 +171,13 @@ impl BuildChunkingContext {
module: Vc<Box<dyn EcmascriptChunkPlaceable>>,
evaluatable_assets: Vc<EvaluatableAssets>,
availability_info: Value<AvailabilityInfo>,
) -> Result<Vc<Box<dyn OutputAsset>>> {
) -> Result<Vc<EntryChunkGroupResult>> {
let availability_info = availability_info.into_value();

let MakeChunkGroupResult { chunks } = make_chunk_group(
let MakeChunkGroupResult {
chunks,
availability_info,
} = make_chunk_group(
Vc::upcast(self),
once(Vc::upcast(module)).chain(
evaluatable_assets
Expand All @@ -192,7 +202,11 @@ impl BuildChunkingContext {
module,
));

Ok(asset)
Ok(EntryChunkGroupResult {
asset,
availability_info,
}
.cell())
}

#[turbo_tasks::function]
Expand Down Expand Up @@ -313,10 +327,13 @@ impl ChunkingContext for BuildChunkingContext {
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
availability_info: Value<AvailabilityInfo>,
) -> Result<Vc<OutputAssets>> {
) -> Result<Vc<ChunkGroupResult>> {
let span = tracing::info_span!("chunking", module = *module.ident().to_string().await?);
async move {
let MakeChunkGroupResult { chunks } = make_chunk_group(
let MakeChunkGroupResult {
chunks,
availability_info,
} = make_chunk_group(
Vc::upcast(self),
[Vc::upcast(module)],
availability_info.into_value(),
Expand All @@ -333,19 +350,23 @@ impl ChunkingContext for BuildChunkingContext {
*asset = asset.resolve().await?;
}

Ok(Vc::cell(assets))
Ok(ChunkGroupResult {
assets: Vc::cell(assets),
availability_info,
}
.cell())
}
.instrument(span)
.await
}

#[turbo_tasks::function]
async fn evaluated_chunk_group(
fn evaluated_chunk_group(
self: Vc<Self>,
_ident: Vc<AssetIdent>,
_evaluatable_assets: Vc<EvaluatableAssets>,
_availability_info: Value<AvailabilityInfo>,
) -> Result<Vc<OutputAssets>> {
) -> Result<Vc<ChunkGroupResult>> {
// TODO(alexkirsz) This method should be part of a separate trait that is
// only implemented for client/edge runtimes.
bail!("the build chunking context does not support evaluated chunk groups")
Expand Down
46 changes: 24 additions & 22 deletions crates/turbopack-cli/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,32 +247,34 @@ async fn build_internal(
if let Some(ecmascript) =
Vc::try_resolve_downcast_type::<EcmascriptModuleAsset>(entry_module).await?
{
Vc::cell(vec![Vc::try_resolve_downcast_type::<BuildChunkingContext>(
chunking_context,
)
.await?
.unwrap()
.entry_chunk_group(
build_output_root
.join(
ecmascript
.ident()
.path()
.file_stem()
.await?
.as_deref()
.unwrap()
.to_string(),
Vc::cell(vec![
Vc::try_resolve_downcast_type::<BuildChunkingContext>(chunking_context)
.await?
.unwrap()
.entry_chunk_group(
build_output_root
.join(
ecmascript
.ident()
.path()
.file_stem()
.await?
.as_deref()
.unwrap()
.to_string(),
)
.with_extension("entry.js".to_string()),
Vc::upcast(ecmascript),
EvaluatableAssets::one(Vc::upcast(ecmascript)),
Value::new(AvailabilityInfo::Root),
)
.with_extension("entry.js".to_string()),
Vc::upcast(ecmascript),
EvaluatableAssets::one(Vc::upcast(ecmascript)),
Value::new(AvailabilityInfo::Root),
)])
.await?
.asset,
])
} else if let Some(chunkable) =
Vc::try_resolve_sidecast::<Box<dyn ChunkableModule>>(entry_module).await?
{
chunking_context.root_chunk_group(chunkable)
chunking_context.root_chunk_group_assets(chunkable)
} else {
// TODO convert into a serve-able asset
bail!(
Expand Down
55 changes: 27 additions & 28 deletions crates/turbopack-core/src/chunk/chunk_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{module::Module, output::OutputAssets, reference::ModuleReference};

pub struct MakeChunkGroupResult {
pub chunks: Vec<Vc<Box<dyn Chunk>>>,
pub availability_info: AvailabilityInfo,
}

/// Creates a chunk group from a set of entries.
Expand Down Expand Up @@ -100,35 +101,30 @@ pub async fn make_chunk_group(
);
}

// Insert async chunk loaders for every referenced async module
let async_loaders = if async_modules.is_empty() {
vec![]
} else {
// Compute new [AvailabilityInfo]
let inner_availability_info = {
let map = chunk_items
.iter()
.map(|(&chunk_item, async_info)| {
(
chunk_item,
AvailableChunkItemInfo {
is_async: async_info.is_some(),
},
)
})
.collect();
let map = Vc::cell(map);
availability_info.with_chunk_items(map).await?
};

async_modules
.into_iter()
.map(|module| {
chunking_context
.async_loader_chunk_item(module, Value::new(inner_availability_info))
// Compute new [AvailabilityInfo]
let availability_info = {
let map = chunk_items
.iter()
.map(|(&chunk_item, async_info)| {
(
chunk_item,
AvailableChunkItemInfo {
is_async: async_info.is_some(),
},
)
})
.collect::<Vec<_>>()
.collect();
let map = Vc::cell(map);
availability_info.with_chunk_items(map).await?
};

// Insert async chunk loaders for every referenced async module
let async_loaders = async_modules
.into_iter()
.map(|module| {
chunking_context.async_loader_chunk_item(module, Value::new(availability_info))
})
.collect::<Vec<_>>();
let async_loader_chunk_items = async_loaders.iter().map(|&chunk_item| (chunk_item, None));

// And also add output assets referenced by async chunk loaders
Expand Down Expand Up @@ -165,7 +161,10 @@ pub async fn make_chunk_group(
// concatenate chunks
chunks.extend(async_loader_chunks);

Ok(MakeChunkGroupResult { chunks })
Ok(MakeChunkGroupResult {
chunks,
availability_info,
})
}

async fn references_to_output_assets(
Expand Down
106 changes: 102 additions & 4 deletions crates/turbopack-core/src/chunk/chunking_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ use crate::{
output::{OutputAsset, OutputAssets},
};

#[turbo_tasks::value(shared)]
pub struct ChunkGroupResult {
pub assets: Vc<OutputAssets>,
pub availability_info: AvailabilityInfo,
}

/// A context for the chunking that influences the way chunks are created
#[turbo_tasks::value_trait]
pub trait ChunkingContext {
Expand Down Expand Up @@ -62,14 +68,14 @@ pub trait ChunkingContext {
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets>;
) -> Vc<ChunkGroupResult>;

fn evaluated_chunk_group(
self: Vc<Self>,
ident: Vc<AssetIdent>,
evaluatable_assets: Vc<EvaluatableAssets>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets>;
) -> Vc<ChunkGroupResult>;

async fn chunk_item_id_from_ident(
self: Vc<Self>,
Expand All @@ -84,13 +90,105 @@ pub trait ChunkingContext {
}

pub trait ChunkingContextExt {
fn root_chunk_group(self: Vc<Self>, module: Vc<Box<dyn ChunkableModule>>) -> Vc<OutputAssets>
fn root_chunk_group(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
) -> Vc<ChunkGroupResult>
where
Self: Send;

fn root_chunk_group_assets(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
) -> Vc<OutputAssets>
where
Self: Send;

fn evaluated_chunk_group_assets(
self: Vc<Self>,
ident: Vc<AssetIdent>,
evaluatable_assets: Vc<EvaluatableAssets>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets>
where
Self: Send;

fn chunk_group_assets(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets>
where
Self: Send;
}

impl<T: ChunkingContext + Send + Upcast<Box<dyn ChunkingContext>>> ChunkingContextExt for T {
fn root_chunk_group(self: Vc<Self>, module: Vc<Box<dyn ChunkableModule>>) -> Vc<OutputAssets> {
fn root_chunk_group(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
) -> Vc<ChunkGroupResult> {
self.chunk_group(module, Value::new(AvailabilityInfo::Root))
}

fn root_chunk_group_assets(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
) -> Vc<OutputAssets> {
root_chunk_group_assets(Vc::upcast(self), module)
}

fn evaluated_chunk_group_assets(
self: Vc<Self>,
ident: Vc<AssetIdent>,
evaluatable_assets: Vc<EvaluatableAssets>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets> {
evaluated_chunk_group_assets(
Vc::upcast(self),
ident,
evaluatable_assets,
availability_info,
)
}

fn chunk_group_assets(
self: Vc<Self>,
module: Vc<Box<dyn ChunkableModule>>,
availability_info: Value<AvailabilityInfo>,
) -> Vc<OutputAssets> {
chunk_group_assets(Vc::upcast(self), module, availability_info)
}
}

#[turbo_tasks::function]
async fn root_chunk_group_assets(
chunking_context: Vc<Box<dyn ChunkingContext>>,
module: Vc<Box<dyn ChunkableModule>>,
) -> Result<Vc<OutputAssets>> {
Ok(chunking_context.root_chunk_group(module).await?.assets)
}

#[turbo_tasks::function]
async fn evaluated_chunk_group_assets(
chunking_context: Vc<Box<dyn ChunkingContext>>,
ident: Vc<AssetIdent>,
evaluatable_assets: Vc<EvaluatableAssets>,
availability_info: Value<AvailabilityInfo>,
) -> Result<Vc<OutputAssets>> {
Ok(chunking_context
.evaluated_chunk_group(ident, evaluatable_assets, availability_info)
.await?
.assets)
}

#[turbo_tasks::function]
async fn chunk_group_assets(
chunking_context: Vc<Box<dyn ChunkingContext>>,
module: Vc<Box<dyn ChunkableModule>>,
availability_info: Value<AvailabilityInfo>,
) -> Result<Vc<OutputAssets>> {
Ok(chunking_context
.chunk_group(module, availability_info)
.await?
.assets)
}
2 changes: 1 addition & 1 deletion crates/turbopack-core/src/chunk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use turbo_tasks_hash::DeterministicHash;

use self::availability_info::AvailabilityInfo;
pub use self::{
chunking_context::{ChunkingContext, ChunkingContextExt},
chunking_context::{ChunkGroupResult, ChunkingContext, ChunkingContextExt},
data::{ChunkData, ChunkDataOption, ChunksData},
evaluate::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets},
passthrough_asset::PassthroughModule,
Expand Down
4 changes: 2 additions & 2 deletions crates/turbopack-dev-server/src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ impl DevHtmlAsset {
} else {
runtime_entries
};
chunking_context.evaluated_chunk_group(
chunking_context.evaluated_chunk_group_assets(
chunkable_module.ident(),
runtime_entries,
Value::new(AvailabilityInfo::Root),
)
} else {
chunking_context.root_chunk_group(Vc::upcast(chunkable_module))
chunking_context.root_chunk_group_assets(Vc::upcast(chunkable_module))
};

assets.await
Expand Down
Loading

0 comments on commit e3ad207

Please sign in to comment.