turbopack_resolve/resolve_options_context.rs
1use anyhow::Result;
2use bincode::{Decode, Encode};
3use turbo_rcstr::RcStr;
4use turbo_tasks::{NonLocalValue, ResolvedVc, ValueDefault, Vc};
5use turbo_tasks_fs::FileSystemPath;
6use turbopack_core::{
7 condition::ContextCondition,
8 environment::Environment,
9 resolve::{
10 options::{ConditionValue, ImportMap, ResolvedMap},
11 plugin::{AfterResolvePlugin, BeforeResolvePlugin},
12 },
13};
14
15#[derive(Default, Debug, Clone, PartialEq, Eq, NonLocalValue, Encode, Decode)]
16pub enum TsConfigHandling {
17 /// Ignore tsconfig and jsconfig files.
18 Disabled,
19 #[default]
20 /// Find corresponding tsconfig files based on the location of the file.
21 ContextFile,
22 /// Use the provided config file for all files if it exists, otherwise fall back to the
23 /// [`Self::ContextFile`] behavior.
24 Fixed(FileSystemPath),
25}
26
27#[turbo_tasks::value(shared)]
28#[derive(Default, Clone)]
29pub struct ResolveOptionsContext {
30 /// - Overrides `options.node_externals`
31 /// - Appends `environment.resolve_conditions`
32 /// - Overrides `options.extensions`
33 pub emulate_environment: Option<ResolvedVc<Environment>>,
34 pub enable_types: bool,
35 pub enable_typescript: bool,
36 pub enable_react: bool,
37 pub enable_node_native_modules: bool,
38 // Enable resolving of .mjs files without the .mjs extension
39 pub enable_mjs_extension: bool,
40 /// Enable resolving of the node_modules folder when within the provided
41 /// directory
42 pub enable_node_modules: Option<FileSystemPath>,
43 /// A specific path to a tsconfig.json file to use for resolving modules. If `None`, one will
44 /// be looked up through the filesystem
45 pub tsconfig_path: TsConfigHandling,
46 /// Mark well-known Node.js modules as external imports and load them using
47 /// native `require`. e.g. url, querystring, os
48 pub enable_node_externals: bool,
49 /// Mark well-known Edge modules as external imports and load them using
50 /// native `require`. e.g. buffer, events, assert
51 pub enable_edge_node_externals: bool,
52 /// Enables the "browser" field and export condition in package.json
53 pub browser: bool,
54 /// Enables the "module" field and export condition in package.json
55 pub module: bool,
56 /// Enables the "module-sync" export condition in package.json
57 pub module_sync: ConditionValue,
58 pub custom_conditions: Vec<RcStr>,
59 pub custom_extensions: Option<Vec<RcStr>>,
60 /// An additional import map to use when resolving modules.
61 ///
62 /// If set, this import map will be applied to `ResolveOption::import_map`.
63 /// It is always applied last, so any mapping defined within will take
64 /// precedence over any other (e.g. tsconfig.json `compilerOptions.paths`).
65 pub import_map: Option<ResolvedVc<ImportMap>>,
66 /// An import map to fall back to when a request could not be resolved.
67 ///
68 /// If set, this import map will be applied to
69 /// `ResolveOption::fallback_import_map`. It is always applied last, so
70 /// any mapping defined within will take precedence over any other.
71 pub fallback_import_map: Option<ResolvedVc<ImportMap>>,
72 /// An additional resolved map to use after modules have been resolved.
73 pub resolved_map: Option<ResolvedVc<ResolvedMap>>,
74 /// A list of rules to use a different resolve option context for certain
75 /// context paths. The first matching is used.
76 pub rules: Vec<(ContextCondition, ResolvedVc<ResolveOptionsContext>)>,
77 /// Plugins which get applied before and after resolving.
78 pub after_resolve_plugins: Vec<ResolvedVc<Box<dyn AfterResolvePlugin>>>,
79 pub before_resolve_plugins: Vec<ResolvedVc<Box<dyn BeforeResolvePlugin>>>,
80 /// Warn instead of error for resolve errors
81 pub loose_errors: bool,
82 /// Collect affecting sources for each resolve result. Useful for tracing.
83 pub collect_affecting_sources: bool,
84 /// The directory that a request starting with `/` resolves from, e.g. `/dir/file.js`. When
85 /// unset, such a request isn't supported and reports an issue saying so.
86 ///
87 /// Sets [`ResolveOptions::server_relative_root`].
88 ///
89 /// [`ResolveOptions::server_relative_root`]:
90 /// turbopack_core::resolve::options::ResolveOptions::server_relative_root
91 pub server_relative_root: Option<FileSystemPath>,
92
93 pub placeholder_for_future_extensions: (),
94}
95
96#[turbo_tasks::value_impl]
97impl ResolveOptionsContext {
98 #[turbo_tasks::function]
99 pub async fn with_types_enabled(self: Vc<Self>) -> Result<Vc<Self>> {
100 let mut clone = self.owned().await?;
101 clone.enable_types = true;
102 clone.enable_typescript = true;
103 Ok(Self::cell(clone))
104 }
105
106 /// Returns a new [`Vc<ResolveOptionsContext>`][Self] with its import map extended to include
107 /// the given import map.
108 #[turbo_tasks::function]
109 pub async fn with_extended_import_map(
110 self: Vc<Self>,
111 import_map: Vc<ImportMap>,
112 ) -> Result<Vc<Self>> {
113 let mut resolve_options_context = self.owned().await?;
114 resolve_options_context.import_map = Some(
115 resolve_options_context
116 .import_map
117 .map(|current_import_map| current_import_map.extend(import_map))
118 .unwrap_or(import_map)
119 .to_resolved()
120 .await?,
121 );
122 Ok(resolve_options_context.cell())
123 }
124
125 /// Returns a new [`Vc<ResolveOptionsContext>`][Self] with its fallback import map extended to
126 /// include the given import map.
127 #[turbo_tasks::function]
128 pub async fn with_extended_fallback_import_map(
129 self: Vc<Self>,
130 fallback_import_map: Vc<ImportMap>,
131 ) -> Result<Vc<Self>> {
132 let mut resolve_options_context = self.owned().await?;
133 resolve_options_context.fallback_import_map = Some(
134 resolve_options_context
135 .fallback_import_map
136 .map(|current_fallback_import_map| {
137 current_fallback_import_map.extend(fallback_import_map)
138 })
139 .unwrap_or(fallback_import_map)
140 .to_resolved()
141 .await?,
142 );
143 Ok(resolve_options_context.cell())
144 }
145}
146
147#[turbo_tasks::value_impl]
148impl ValueDefault for ResolveOptionsContext {
149 #[turbo_tasks::function]
150 fn value_default() -> Vc<Self> {
151 Self::cell(Default::default())
152 }
153}