turbopack_core/chunk/
module_id_strategies.rs

1use anyhow::{Result, bail};
2use rustc_hash::FxHashMap;
3use turbo_tasks::{ResolvedVc, ValueToString, Vc};
4use turbo_tasks_hash::hash_xxh3_hash64;
5
6use super::ModuleId;
7use crate::ident::AssetIdent;
8
9#[turbo_tasks::value_trait]
10pub trait ModuleIdStrategy {
11    #[turbo_tasks::function]
12    fn get_module_id(self: Vc<Self>, ident: Vc<AssetIdent>) -> Vc<ModuleId>;
13}
14
15#[turbo_tasks::value]
16pub struct DevModuleIdStrategy;
17
18impl DevModuleIdStrategy {
19    pub fn new() -> Vc<Self> {
20        DevModuleIdStrategy {}.cell()
21    }
22
23    pub fn new_resolved() -> ResolvedVc<Self> {
24        DevModuleIdStrategy {}.resolved_cell()
25    }
26}
27
28#[turbo_tasks::value_impl]
29impl ModuleIdStrategy for DevModuleIdStrategy {
30    #[turbo_tasks::function]
31    async fn get_module_id(self: Vc<Self>, ident: Vc<AssetIdent>) -> Result<Vc<ModuleId>> {
32        Ok(ModuleId::String(ident.to_string().owned().await?).cell())
33    }
34}
35
36#[turbo_tasks::value(shared)]
37pub struct GlobalModuleIdStrategy {
38    pub module_id_map: FxHashMap<ResolvedVc<AssetIdent>, u64>,
39}
40
41#[turbo_tasks::value_impl]
42impl ModuleIdStrategy for GlobalModuleIdStrategy {
43    #[turbo_tasks::function]
44    async fn get_module_id(&self, ident: ResolvedVc<AssetIdent>) -> Result<Vc<ModuleId>> {
45        if let Some(module_id) = self.module_id_map.get(&ident) {
46            const JS_MAX_SAFE_INTEGER: u64 = (1u64 << 53) - 1;
47            if *module_id > JS_MAX_SAFE_INTEGER {
48                bail!("Numeric module id is too large: {}", module_id);
49            }
50            return Ok(ModuleId::Number(*module_id).cell());
51        }
52
53        let ident_string = ident.to_string().await?;
54        if ident_string.ends_with("[app-client] (ecmascript, next/dynamic entry)") {
55            // TODO: This shouldn't happen, but is a temporary workaround to ignore next/dynamic
56            // imports of a server component from another server component.
57            return Ok(ModuleId::String(
58                hash_xxh3_hash64(ident.to_string().await?)
59                    .to_string()
60                    .into(),
61            )
62            .cell());
63        }
64
65        bail!("ModuleId not found for ident: {ident_string:?}");
66    }
67}