From dad324e72391195cecc26b2890d76a108a5d794d Mon Sep 17 00:00:00 2001 From: fireairforce <32598811+fireairforce@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:20:36 +0800 Subject: [PATCH 1/2] fix(turbopack): honor default chunk content hashing --- .../turbopack-browser/src/chunking_context.rs | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/turbopack/crates/turbopack-browser/src/chunking_context.rs b/turbopack/crates/turbopack-browser/src/chunking_context.rs index 5b267c4c8cfb..7e832aa689b0 100644 --- a/turbopack/crates/turbopack-browser/src/chunking_context.rs +++ b/turbopack/crates/turbopack-browser/src/chunking_context.rs @@ -804,11 +804,11 @@ impl ChunkingContext for BrowserChunkingContext { let ChunkPathInfo { root_path, chunk_root_path, - chunk_content_hashing: _, + chunk_content_hashing, } = &*self.chunk_path_info().await?; let output_name = ident - .output_name(root_path.clone(), prefix, extension.clone()) + .output_name(root_path.clone(), prefix.clone(), extension.clone()) .owned() .await?; @@ -850,8 +850,9 @@ impl ChunkingContext for BrowserChunkingContext { } }; - match filename_template { - Some(filename) => { + // Explicit templates take precedence over the default content-hashed names. + match (filename_template, *chunk_content_hashing) { + (Some(filename), _) => { let mut filename = filename.to_string(); let name = escape_file_path(name); @@ -877,10 +878,31 @@ impl ChunkingContext for BrowserChunkingContext { filename } - None => name.to_string(), + (None, Some(ContentHashing::Direct { length })) => { + let hash = asset + .content() + .content_hash(no_hash_salt(), HashAlgorithm::Xxh3Hash128Base38) + .await?; + let hash = hash.as_ref().context( + "chunk_path requires an asset with file content when content hashing \ + is enabled", + )?; + let hash = &hash[..length as usize]; + if let Some(prefix) = prefix { + format!("{prefix}-{hash}") + } else { + hash.to_string() + } + } + (None, None) => name.to_string(), + } + } + None => { + if chunk_content_hashing.is_some() { + bail!("chunk_path requires an asset when content hashing is enabled"); } + output_name.to_string() } - None => output_name.to_string(), }; if !filename.ends_with(extension.as_str()) { From 552072ebb485523ccb0a1e6770dadcd06e3c55ca Mon Sep 17 00:00:00 2001 From: fireairforce <32598811+fireairforce@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:44:59 +0800 Subject: [PATCH 2/2] fix(turbopack): respect hash salt and bound chunk hash length --- turbopack/crates/turbopack-browser/src/chunking_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/turbopack/crates/turbopack-browser/src/chunking_context.rs b/turbopack/crates/turbopack-browser/src/chunking_context.rs index 7e832aa689b0..67ac0f6226ab 100644 --- a/turbopack/crates/turbopack-browser/src/chunking_context.rs +++ b/turbopack/crates/turbopack-browser/src/chunking_context.rs @@ -881,13 +881,13 @@ impl ChunkingContext for BrowserChunkingContext { (None, Some(ContentHashing::Direct { length })) => { let hash = asset .content() - .content_hash(no_hash_salt(), HashAlgorithm::Xxh3Hash128Base38) + .content_hash(*this.hash_salt, HashAlgorithm::Xxh3Hash128Base38) .await?; let hash = hash.as_ref().context( "chunk_path requires an asset with file content when content hashing \ is enabled", )?; - let hash = &hash[..length as usize]; + let hash = &hash[..min(length as usize, hash.len())]; if let Some(prefix) = prefix { format!("{prefix}-{hash}") } else {