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, turbobail,
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(Default, Clone, PartialEq, Eq, ValueDebugFormat, NonLocalValue, Encode, Decode)]
16pub enum ModuleIdFallback {
17 Error,
18 IdentWithoutLayer,
19 #[default]
20 Ident,
21}
22
23#[turbo_tasks::value(shared)]
24#[derive(Default)]
25pub struct ModuleIdStrategy {
26 pub module_id_map: Option<ResolvedVc<ModuleIds>>,
27 pub fallback: ModuleIdFallback,
28}
29
30#[turbo_tasks::value_impl]
31impl ModuleIdStrategy {
32 #[turbo_tasks::function]
33 pub fn new_ident_without_layer() -> Vc<Self> {
34 Self {
35 module_id_map: None,
36 fallback: ModuleIdFallback::IdentWithoutLayer,
37 }
38 .cell()
39 }
40}
41
42impl ModuleIdStrategy {
43 pub async fn get_id(&self, chunk_item: Vc<Box<dyn ChunkItem>>) -> Result<ModuleId> {
44 let ident = chunk_item.asset_ident();
45 self.get_id_from_ident(ident).await
46 }
47
48 pub async fn get_id_from_module(&self, module: Vc<Box<dyn Module>>) -> Result<ModuleId> {
49 let ident = module.ident();
50 self.get_id_from_ident(ident).await
51 }
52
53 pub async fn get_id_from_ident(&self, ident: Vc<AssetIdent>) -> Result<ModuleId> {
54 let ident = ident.to_resolved().await?;
55 if let Some(module_id_map) = self.module_id_map
56 && let Some(module_id) = module_id_map.get(&ident).await?.as_deref().cloned()
57 {
58 return Ok(module_id);
59 }
60
61 match self.fallback {
62 ModuleIdFallback::Error => {
63 let ident_string = ident.to_string().await?;
64 if ident_string.ends_with("[app-client] (ecmascript, next/dynamic entry)") {
65 return Ok(ModuleId::String(
69 hash_xxh3_hash64(ident.to_string().await?)
70 .to_string()
71 .into(),
72 ));
73 }
74
75 turbobail!("ModuleId not found for ident: {}", ident);
76 }
77 ModuleIdFallback::IdentWithoutLayer => Ok(ModuleId::String(
78 ident.to_string_without_layer().owned().await?,
79 )),
80 ModuleIdFallback::Ident => Ok(ModuleId::String(ident.to_string().owned().await?)),
81 }
82 }
83}