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