turbopack/module_options/
module_options_context.rs1use std::fmt::Debug;
2
3use anyhow::Result;
4use bincode::{Decode, Encode};
5use turbo_esregex::EsRegex;
6use turbo_rcstr::{RcStr, rcstr};
7use turbo_tasks::{NonLocalValue, ResolvedVc, ValueDefault, Vc, trace::TraceRawVcs};
8use turbo_tasks_fs::{
9 FileSystemPath,
10 glob::{Glob, GlobOptions},
11};
12use turbopack_core::{
13 chunk::SourceMapsType, compile_time_info::CompileTimeInfo, condition::ContextCondition,
14 environment::Environment, resolve::options::ImportMapping,
15};
16use turbopack_ecmascript::{
17 AnalyzeMode, TreeShakingMode, TypeofWindow, references::esm::UrlRewriteBehavior,
18 transform::PresetEnvConfig,
19};
20pub use turbopack_mdx::MdxTransformOptions;
21use turbopack_node::{
22 execution_context::ExecutionContext,
23 transforms::{postcss::PostCssTransformOptions, webpack::WebpackLoaderItems},
24};
25
26use super::ModuleRule;
27use crate::module_options::RuleCondition;
28
29#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
30pub struct LoaderRuleItem {
31 pub loaders: ResolvedVc<WebpackLoaderItems>,
32 pub rename_as: Option<RcStr>,
33 pub condition: Option<ConditionItem>,
34 pub module_type: Option<RcStr>,
35}
36
37#[derive(Default)]
43#[turbo_tasks::value(transparent)]
44pub struct WebpackRules(Vec<(RcStr, LoaderRuleItem)>);
45
46#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
47pub enum ConditionPath {
48 Glob(RcStr),
49 Regex(ResolvedVc<EsRegex>),
50}
51
52#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
53pub enum ConditionQuery {
54 Constant(RcStr),
55 Regex(ResolvedVc<EsRegex>),
56}
57
58#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
59pub enum ConditionContentType {
60 Glob(RcStr),
61 Regex(ResolvedVc<EsRegex>),
62}
63
64#[turbo_tasks::value(shared)]
65#[derive(Clone, Debug)]
66pub enum ConditionItem {
67 All(Box<[ConditionItem]>),
68 Any(Box<[ConditionItem]>),
69 Not(Box<ConditionItem>),
70 Builtin(RcStr),
71 Base {
72 path: Option<ConditionPath>,
73 content: Option<ResolvedVc<EsRegex>>,
74 query: Option<ConditionQuery>,
75 content_type: Option<ConditionContentType>,
76 },
77}
78
79#[turbo_tasks::value(shared)]
80#[derive(Clone, Debug)]
81pub struct WebpackLoadersOptions {
82 pub rules: ResolvedVc<WebpackRules>,
83 pub builtin_conditions: ResolvedVc<Box<dyn WebpackLoaderBuiltinConditionSet>>,
84 pub loader_runner_package: Option<ResolvedVc<ImportMapping>>,
85}
86
87pub enum WebpackLoaderBuiltinConditionSetMatch {
88 Matched,
89 Unmatched,
90 Invalid,
92}
93
94#[turbo_tasks::value_trait]
97pub trait WebpackLoaderBuiltinConditionSet {
98 fn match_condition(&self, condition: &str) -> WebpackLoaderBuiltinConditionSetMatch;
101}
102
103#[turbo_tasks::value]
106pub struct EmptyWebpackLoaderBuiltinConditionSet;
107
108#[turbo_tasks::value_impl]
109impl EmptyWebpackLoaderBuiltinConditionSet {
110 #[turbo_tasks::function]
111 fn new() -> Vc<Box<dyn WebpackLoaderBuiltinConditionSet>> {
112 Vc::upcast::<Box<dyn WebpackLoaderBuiltinConditionSet>>(
113 EmptyWebpackLoaderBuiltinConditionSet.cell(),
114 )
115 }
116}
117
118#[turbo_tasks::value_impl]
119impl WebpackLoaderBuiltinConditionSet for EmptyWebpackLoaderBuiltinConditionSet {
120 fn match_condition(&self, _condition: &str) -> WebpackLoaderBuiltinConditionSetMatch {
121 WebpackLoaderBuiltinConditionSetMatch::Invalid
122 }
123}
124
125#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
129pub enum DecoratorsKind {
130 Ecma,
136
137 Legacy,
148}
149
150#[turbo_tasks::value(shared)]
157#[derive(Default, Clone, Debug)]
158pub struct DecoratorsOptions {
159 pub decorators_kind: Option<DecoratorsKind>,
160 pub emit_decorators_metadata: bool,
165 pub decorators_before_export: bool,
174 pub use_define_for_class_fields: bool,
175}
176
177#[turbo_tasks::value_impl]
178impl ValueDefault for DecoratorsOptions {
179 #[turbo_tasks::function]
180 fn value_default() -> Vc<Self> {
181 Self::default().cell()
182 }
183}
184
185#[turbo_tasks::value(shared)]
188#[derive(Default, Clone, Debug)]
189pub struct TypescriptTransformOptions {
190 pub use_define_for_class_fields: bool,
191 pub verbatim_module_syntax: bool,
192}
193
194#[turbo_tasks::value_impl]
195impl ValueDefault for TypescriptTransformOptions {
196 #[turbo_tasks::function]
197 fn value_default() -> Vc<Self> {
198 Self::default().cell()
199 }
200}
201
202#[turbo_tasks::value(shared)]
203#[derive(Default, Clone, Debug)]
204pub struct JsxTransformOptions {
205 pub development: bool,
206 pub react_refresh: bool,
207 pub import_source: Option<RcStr>,
208 pub runtime: Option<RcStr>,
209}
210
211#[turbo_tasks::value(shared)]
212#[derive(Clone, Debug)]
213pub struct ExternalsTracingOptions {
214 pub tracing_root: FileSystemPath,
216 pub compile_time_info: ResolvedVc<CompileTimeInfo>,
217}
218
219#[turbo_tasks::value(shared)]
220#[derive(Clone, Default)]
221pub struct ModuleOptionsContext {
222 pub ecmascript: EcmascriptOptionsContext,
223 pub css: CssOptionsContext,
224
225 pub enable_postcss_transform: Option<ResolvedVc<PostCssTransformOptions>>,
226 pub enable_webpack_loaders: Option<ResolvedVc<WebpackLoadersOptions>>,
227 pub enable_mdx: bool,
230 pub enable_mdx_rs: Option<ResolvedVc<MdxTransformOptions>>,
231
232 pub environment: Option<ResolvedVc<Environment>>,
233 pub execution_context: Option<ResolvedVc<ExecutionContext>>,
234 pub side_effect_free_packages: Option<ResolvedVc<Glob>>,
235 pub tree_shaking_mode: Option<TreeShakingMode>,
236
237 pub static_url_tag: Option<RcStr>,
238
239 pub enable_externals_tracing: Option<ResolvedVc<ExternalsTracingOptions>>,
242
243 pub keep_last_successful_parse: bool,
247
248 pub module_rules: Vec<ModuleRule>,
250 pub rules: Vec<(ContextCondition, ResolvedVc<ModuleOptionsContext>)>,
253
254 pub analyze_mode: AnalyzeMode,
257
258 pub placeholder_for_future_extensions: (),
259}
260
261#[turbo_tasks::value(shared)]
262#[derive(Clone, Default)]
263pub struct EcmascriptOptionsContext {
264 pub enable_typeof_window_inlining: Option<TypeofWindow>,
268 pub enable_jsx: Option<ResolvedVc<JsxTransformOptions>>,
269 pub enable_types: bool,
272 pub enable_typescript_transform: Option<ResolvedVc<TypescriptTransformOptions>>,
273 pub enable_decorators: Option<ResolvedVc<DecoratorsOptions>>,
274 pub esm_url_rewrite_behavior: Option<UrlRewriteBehavior>,
275 pub import_externals: bool,
278 pub ignore_dynamic_requests: bool,
282 pub source_maps: SourceMapsType,
284
285 pub enable_exports_info_inlining: bool,
287
288 pub enable_import_as_bytes: bool,
290
291 pub enable_import_as_text: bool,
293
294 pub inline_helpers: bool,
296
297 pub infer_module_side_effects: bool,
299
300 pub preset_env_config: Option<ResolvedVc<PresetEnvConfig>>,
302
303 pub placeholder_for_future_extensions: (),
304}
305
306#[turbo_tasks::value(shared)]
307#[derive(Clone, Default)]
308pub struct CssOptionsContext {
309 pub enable_raw_css: bool,
315
316 pub source_maps: SourceMapsType,
318
319 pub module_css_condition: Option<RuleCondition>,
323
324 pub lightningcss_features: turbopack_css::LightningCssFeatureFlags,
326
327 pub placeholder_for_future_extensions: (),
328}
329
330#[turbo_tasks::value_impl]
331impl ValueDefault for ModuleOptionsContext {
332 #[turbo_tasks::function]
333 fn value_default() -> Vc<Self> {
334 Self::cell(Default::default())
335 }
336}
337
338#[turbo_tasks::function]
339pub async fn side_effect_free_packages_glob(
340 side_effect_free_packages: ResolvedVc<Vec<RcStr>>,
341) -> Result<Vc<Glob>> {
342 let side_effect_free_packages = &*side_effect_free_packages.await?;
343 if side_effect_free_packages.is_empty() {
344 return Ok(Glob::new(rcstr!(""), GlobOptions::default()));
345 }
346
347 let mut globs = String::new();
348 globs.push_str("**/node_modules/{");
349 globs.push_str(&side_effect_free_packages.join(","));
350 globs.push_str("}/**");
351
352 Ok(Glob::new(globs.into(), GlobOptions::default()))
353}