turbopack_ecmascript/references/
node.rs

1use anyhow::Result;
2use tracing::Instrument;
3use turbo_rcstr::RcStr;
4use turbo_tasks::{ResolvedVc, ValueToString, Vc};
5use turbo_tasks_fs::FileSystemPath;
6use turbopack_core::{
7    chunk::{ChunkableModuleReference, ChunkingType, ChunkingTypeOption},
8    context::AssetContext,
9    file_source::FileSource,
10    issue::IssueSource,
11    raw_module::RawModule,
12    reference::ModuleReference,
13    reference_type::{ReferenceType, WorkerReferenceSubType},
14    resolve::{ModuleResolveResult, pattern::Pattern, resolve_raw},
15};
16
17use crate::references::util::check_and_emit_too_many_matches_warning;
18
19#[turbo_tasks::value]
20#[derive(Hash, Clone, Debug)]
21pub struct PackageJsonReference {
22    pub package_json: FileSystemPath,
23}
24
25#[turbo_tasks::value_impl]
26impl PackageJsonReference {
27    #[turbo_tasks::function]
28    pub fn new(package_json: FileSystemPath) -> Vc<Self> {
29        Self::cell(PackageJsonReference { package_json })
30    }
31}
32
33#[turbo_tasks::value_impl]
34impl ModuleReference for PackageJsonReference {
35    #[turbo_tasks::function]
36    async fn resolve_reference(&self) -> Result<Vc<ModuleResolveResult>> {
37        Ok(*ModuleResolveResult::module(ResolvedVc::upcast(
38            RawModule::new(Vc::upcast(FileSource::new(self.package_json.clone())))
39                .to_resolved()
40                .await?,
41        )))
42    }
43}
44
45#[turbo_tasks::value_impl]
46impl ValueToString for PackageJsonReference {
47    #[turbo_tasks::function]
48    async fn to_string(&self) -> Result<Vc<RcStr>> {
49        Ok(Vc::cell(
50            format!(
51                "package.json {}",
52                self.package_json.value_to_string().await?
53            )
54            .into(),
55        ))
56    }
57}
58
59#[turbo_tasks::value]
60#[derive(Hash, Debug)]
61pub struct FilePathModuleReference {
62    asset_context: ResolvedVc<Box<dyn AssetContext>>,
63    context_dir: FileSystemPath,
64    path: ResolvedVc<Pattern>,
65    collect_affecting_sources: bool,
66    issue_source: IssueSource,
67}
68
69#[turbo_tasks::value_impl]
70impl FilePathModuleReference {
71    #[turbo_tasks::function]
72    pub fn new(
73        asset_context: ResolvedVc<Box<dyn AssetContext>>,
74        context_dir: FileSystemPath,
75        path: ResolvedVc<Pattern>,
76        collect_affecting_sources: bool,
77        issue_source: IssueSource,
78    ) -> Vc<Self> {
79        Self {
80            asset_context,
81            context_dir,
82            path,
83            collect_affecting_sources,
84            issue_source,
85        }
86        .cell()
87    }
88}
89
90// A reference to an module by absolute or cwd-relative file path (e.g. for the
91// worker-threads `new Worker` which has the resolving behavior of `fs.readFile` but should treat
92// the resolve result as an module instead of a raw source).
93#[turbo_tasks::value_impl]
94impl ModuleReference for FilePathModuleReference {
95    #[turbo_tasks::function]
96    async fn resolve_reference(&self) -> Result<Vc<ModuleResolveResult>> {
97        let span = tracing::info_span!(
98            "trace module",
99            pattern = display(self.path.to_string().await?)
100        );
101        async {
102            let result = resolve_raw(
103                self.context_dir.clone(),
104                *self.path,
105                self.collect_affecting_sources,
106                /* force_in_lookup_dir */ false,
107            );
108            let result = self.asset_context.process_resolve_result(
109                result,
110                ReferenceType::Worker(WorkerReferenceSubType::NodeWorker),
111            );
112
113            check_and_emit_too_many_matches_warning(
114                result,
115                self.issue_source,
116                self.context_dir.clone(),
117                self.path,
118            )
119            .await?;
120
121            Ok(result)
122        }
123        .instrument(span)
124        .await
125    }
126}
127#[turbo_tasks::value_impl]
128impl ChunkableModuleReference for FilePathModuleReference {
129    #[turbo_tasks::function]
130    fn chunking_type(&self) -> Vc<ChunkingTypeOption> {
131        Vc::cell(Some(ChunkingType::Traced))
132    }
133}
134
135#[turbo_tasks::value_impl]
136impl ValueToString for FilePathModuleReference {
137    #[turbo_tasks::function]
138    async fn to_string(&self) -> Result<Vc<RcStr>> {
139        Ok(Vc::cell(
140            format!("raw asset {}", self.path.to_string().await?,).into(),
141        ))
142    }
143}