Skip to content
Open
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
141 changes: 119 additions & 22 deletions crates/rspack_core/src/compilation/create_chunk_assets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use async_trait::async_trait;
use rustc_hash::FxHashSet;
use rustc_hash::{FxHashMap, FxHashSet};

use super::*;
use crate::{cache::Cache, compilation::pass::PassExt, logger::Logger};
use crate::{
cache::Cache,
compilation::{CompilationChunkAssetHook, pass::PassExt},
logger::Logger,
};

pub struct CreateChunkAssetsPass;

Expand Down Expand Up @@ -84,13 +88,16 @@ pub async fn create_chunk_assets(
.chunk_by_ukey
.contains(chunk)
});
let chunks: FxHashSet<ChunkUkey> = mutations
.iter()
.filter_map(|mutation| match mutation {
Mutation::ChunkSetHashes { chunk } => Some(*chunk),
_ => None,
})
.collect();
let mut chunks = Vec::new();
let mut seen_chunks = FxHashSet::default();
for chunk in mutations.iter().filter_map(|mutation| match mutation {
Mutation::ChunkSetHashes { chunk } => Some(*chunk),
_ => None,
}) {
if seen_chunks.insert(chunk) {
chunks.push(chunk);
}
}
tracing::debug!(target: incremental::TRACING_TARGET, passes = %IncrementalPasses::CHUNK_ASSET, %mutations);
let logger = compilation.get_logger("rspack.incremental.chunkAsset");
logger.log(format!(
Expand All @@ -105,7 +112,7 @@ pub async fn create_chunk_assets(
.chunk_by_ukey
.keys()
.copied()
.collect()
.collect::<Vec<_>>()
};
let compilation_ref = &*compilation;
let results = rspack_parallel::scope::<_, Result<_>>(|token| {
Expand All @@ -114,7 +121,7 @@ pub async fn create_chunk_assets(
let s = unsafe { token.used((compilation_ref, &plugin_driver, chunk)) };

s.spawn(|(this, plugin_driver, chunk)| async {
let mut manifests = Vec::new();
let mut manifests = Vec::with_capacity(2);
let mut diagnostics = Vec::new();
plugin_driver
.compilation_hooks
Expand All @@ -134,24 +141,93 @@ pub async fn create_chunk_assets(
})
.await;

let mut chunk_render_results = ChunkRenderArtifact::default();
let mut chunk_render_results = Vec::with_capacity(results.len());
for result in results {
let item = result.to_rspack_result()?;
let (key, value) = item?;
chunk_render_results.insert(key, value);
chunk_render_results.push((key, value));
}
let chunk_ukey_and_manifest = if compilation

let has_chunk_asset_hook =
has_chunk_asset_taps(&plugin_driver.compilation_hooks.chunk_asset).await;

if compilation
.incremental
.passes_enabled(IncrementalPasses::CHUNK_ASSET)
{
let mut chunk_render_artifact =
FxHashMap::with_capacity_and_hasher(chunk_render_results.len(), Default::default());
chunk_render_artifact.extend(chunk_render_results);
compilation
.chunk_render_artifact
.extend(chunk_render_results);
compilation.chunk_render_artifact.clone()
} else {
chunk_render_results
};
.extend(ChunkRenderArtifact::from(chunk_render_artifact));
let chunk_render_artifact = compilation.chunk_render_artifact.clone();
if !has_chunk_asset_hook {
emit_chunk_assets_without_hook(compilation, chunk_render_artifact);
} else {
emit_chunk_assets_with_hook(compilation, chunk_render_artifact, plugin_driver).await;
}
return Ok(());
}

if !has_chunk_asset_hook {
emit_chunk_assets_without_hook(compilation, chunk_render_results);
return Ok(());
}

emit_chunk_assets_with_hook(compilation, chunk_render_results, plugin_driver).await;

Ok(())
}

fn emit_chunk_assets_without_hook(
compilation: &mut Compilation,
chunk_ukey_and_manifest: impl IntoIterator<Item = (ChunkUkey, ChunkRenderResult)>,
) {
for (
chunk_ukey,
ChunkRenderResult {
manifests,
diagnostics,
},
) in chunk_ukey_and_manifest
{
if !diagnostics.is_empty() {
compilation.extend_diagnostics(diagnostics);
}

if manifests.is_empty() {
continue;
}

let current_chunk = compilation
.build_chunk_graph_artifact
.chunk_by_ukey
.expect_get_mut(&chunk_ukey);

current_chunk.set_rendered(true);
for file_manifest in &manifests {
if file_manifest.auxiliary {
current_chunk.add_auxiliary_file(file_manifest.filename.clone());
} else {
current_chunk.add_file(file_manifest.filename.clone());
}
}

for file_manifest in manifests {
compilation.emit_asset(
file_manifest.filename,
CompilationAsset::new(Some(file_manifest.source), file_manifest.info),
);
}
}
}

async fn emit_chunk_assets_with_hook(
compilation: &mut Compilation,
chunk_ukey_and_manifest: impl IntoIterator<Item = (ChunkUkey, ChunkRenderResult)>,
plugin_driver: SharedPluginDriver,
) {
for (
chunk_ukey,
ChunkRenderResult {
Expand All @@ -160,7 +236,13 @@ pub async fn create_chunk_assets(
},
) in chunk_ukey_and_manifest
{
compilation.extend_diagnostics(diagnostics);
if !diagnostics.is_empty() {
compilation.extend_diagnostics(diagnostics);
}

if manifests.is_empty() {
continue;
}

for file_manifest in manifests {
let filename = file_manifest.filename;
Expand All @@ -184,8 +266,6 @@ pub async fn create_chunk_assets(
_ = chunk_asset(compilation, chunk_ukey, &filename, plugin_driver.clone()).await;
}
}

Ok(())
}

async fn chunk_asset(
Expand All @@ -201,3 +281,20 @@ async fn chunk_asset(
.await?;
Ok(())
}

async fn has_chunk_asset_taps(hook: &CompilationChunkAssetHook) -> bool {
if !hook.taps.is_empty() {
return true;
}

for interceptor in hook.interceptors.iter() {
let Ok(taps) = interceptor.call(hook).await else {
return true;
};
if !taps.is_empty() {
return true;
}
}

false
}
Loading