turbopack_core/chunk/
chunk_id_strategy.rs1use anyhow::{Result, bail};
2use bincode::{Decode, Encode};
3use rustc_hash::FxHashMap;
4use turbo_tasks::{
5 NonLocalValue, ResolvedVc, ValueToString, Vc, debug::ValueDebugFormat, trace::TraceRawVcs,
6};
7use turbo_tasks_hash::hash_xxh3_hash64;
8
9use super::ModuleId;
10use crate::{chunk::ChunkItem, ident::AssetIdent, module::Module};
11
12#[turbo_tasks::value(transparent, cell = "keyed")]
13pub struct ModuleIds(FxHashMap<ResolvedVc<AssetIdent>, ModuleId>);
14
15#[derive(
16 Default, Clone, PartialEq, Eq, ValueDebugFormat, TraceRawVcs, NonLocalValue, Encode, Decode,
17)]
18pub enum ModuleIdFallback {
19 Error,
20 #[default]
21 Ident,
22}
23
24#[turbo_tasks::value(shared)]
25#[derive(Default)]
26pub struct ModuleIdStrategy {
27 pub module_id_map: Option<ResolvedVc<ModuleIds>>,
28 pub fallback: ModuleIdFallback,
29}
30
31impl ModuleIdStrategy {
32 pub async fn get_id(&self, chunk_item: Vc<Box<dyn ChunkItem>>) -> Result<ModuleId> {
33 let ident = chunk_item.asset_ident();
34 self.get_id_from_ident(ident).await
35 }
36
37 pub async fn get_id_from_module(&self, module: Vc<Box<dyn Module>>) -> Result<ModuleId> {
38 let ident = module.ident();
39 self.get_id_from_ident(ident).await
40 }
41
42 pub async fn get_id_from_ident(&self, ident: Vc<AssetIdent>) -> Result<ModuleId> {
43 let ident = ident.to_resolved().await?;
44 if let Some(module_id_map) = self.module_id_map
45 && let Some(module_id) = module_id_map.get(&ident).await?.as_deref().cloned()
46 {
47 return Ok(module_id);
48 }
49
50 match self.fallback {
51 ModuleIdFallback::Error => {
52 let ident_string = ident.to_string().await?;
53 if ident_string.ends_with("[app-client] (ecmascript, next/dynamic entry)") {
54 return Ok(ModuleId::String(
58 hash_xxh3_hash64(ident.to_string().await?)
59 .to_string()
60 .into(),
61 ));
62 }
63
64 bail!("ModuleId not found for ident: {}", ident.to_string().await?);
65 }
66 ModuleIdFallback::Ident => Ok(ModuleId::String(ident.to_string().owned().await?)),
67 }
68 }
69}