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};
19pub use turbopack_mdx::MdxTransformOptions;
20use turbopack_node::{
21 execution_context::ExecutionContext,
22 transforms::{postcss::PostCssTransformOptions, webpack::WebpackLoaderItems},
23};
24
25use super::ModuleRule;
26use crate::module_options::RuleCondition;
27
28#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
29pub struct LoaderRuleItem {
30 pub loaders: ResolvedVc<WebpackLoaderItems>,
31 pub rename_as: Option<RcStr>,
32 pub condition: Option<ConditionItem>,
33 pub module_type: Option<RcStr>,
34}
35
36#[derive(Default)]
42#[turbo_tasks::value(transparent)]
43pub struct WebpackRules(Vec<(RcStr, LoaderRuleItem)>);
44
45#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
46pub enum ConditionPath {
47 Glob(RcStr),
48 Regex(ResolvedVc<EsRegex>),
49}
50
51#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
52pub enum ConditionQuery {
53 Constant(RcStr),
54 Regex(ResolvedVc<EsRegex>),
55}
56
57#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
58pub enum ConditionContentType {
59 Glob(RcStr),
60 Regex(ResolvedVc<EsRegex>),
61}
62
63#[turbo_tasks::value(shared)]
64#[derive(Clone, Debug)]
65pub enum ConditionItem {
66 All(Box<[ConditionItem]>),
67 Any(Box<[ConditionItem]>),
68 Not(Box<ConditionItem>),
69 Builtin(RcStr),
70 Base {
71 path: Option<ConditionPath>,
72 content: Option<ResolvedVc<EsRegex>>,
73 query: Option<ConditionQuery>,
74 content_type: Option<ConditionContentType>,
75 },
76}
77
78#[turbo_tasks::value(shared)]
79#[derive(Clone, Debug)]
80pub struct WebpackLoadersOptions {
81 pub rules: ResolvedVc<WebpackRules>,
82 pub builtin_conditions: ResolvedVc<Box<dyn WebpackLoaderBuiltinConditionSet>>,
83 pub loader_runner_package: Option<ResolvedVc<ImportMapping>>,
84}
85
86pub enum WebpackLoaderBuiltinConditionSetMatch {
87 Matched,
88 Unmatched,
89 Invalid,
91}
92
93#[turbo_tasks::value_trait]
96pub trait WebpackLoaderBuiltinConditionSet {
97 fn match_condition(&self, condition: &str) -> WebpackLoaderBuiltinConditionSetMatch;
100}
101
102#[turbo_tasks::value]
105pub struct EmptyWebpackLoaderBuiltinConditionSet;
106
107#[turbo_tasks::value_impl]
108impl EmptyWebpackLoaderBuiltinConditionSet {
109 #[turbo_tasks::function]
110 fn new() -> Vc<Box<dyn WebpackLoaderBuiltinConditionSet>> {
111 Vc::upcast::<Box<dyn WebpackLoaderBuiltinConditionSet>>(
112 EmptyWebpackLoaderBuiltinConditionSet.cell(),
113 )
114 }
115}
116
117#[turbo_tasks::value_impl]
118impl WebpackLoaderBuiltinConditionSet for EmptyWebpackLoaderBuiltinConditionSet {
119 fn match_condition(&self, _condition: &str) -> WebpackLoaderBuiltinConditionSetMatch {
120 WebpackLoaderBuiltinConditionSetMatch::Invalid
121 }
122}
123
124#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, NonLocalValue, Encode, Decode)]
128pub enum DecoratorsKind {
129 Ecma,
135
136 Legacy,
147}
148
149#[turbo_tasks::value(shared)]
156#[derive(Default, Clone, Debug)]
157pub struct DecoratorsOptions {
158 pub decorators_kind: Option<DecoratorsKind>,
159 pub emit_decorators_metadata: bool,
164 pub decorators_before_export: bool,
173 pub use_define_for_class_fields: bool,
174}
175
176#[turbo_tasks::value_impl]
177impl ValueDefault for DecoratorsOptions {
178 #[turbo_tasks::function]
179 fn value_default() -> Vc<Self> {
180 Self::default().cell()
181 }
182}
183
184#[turbo_tasks::value(shared)]
187#[derive(Default, Clone, Debug)]
188pub struct TypescriptTransformOptions {
189 pub use_define_for_class_fields: bool,
190 pub verbatim_module_syntax: bool,
191}
192
193#[turbo_tasks::value_impl]
194impl ValueDefault for TypescriptTransformOptions {
195 #[turbo_tasks::function]
196 fn value_default() -> Vc<Self> {
197 Self::default().cell()
198 }
199}
200
201#[turbo_tasks::value(shared)]
202#[derive(Default, Clone, Debug)]
203pub struct JsxTransformOptions {
204 pub development: bool,
205 pub react_refresh: bool,
206 pub import_source: Option<RcStr>,
207 pub runtime: Option<RcStr>,
208}
209
210#[turbo_tasks::value(shared)]
211#[derive(Clone, Debug)]
212pub struct ExternalsTracingOptions {
213 pub tracing_root: FileSystemPath,
215 pub compile_time_info: ResolvedVc<CompileTimeInfo>,
216}
217
218#[turbo_tasks::value(shared)]
219#[derive(Clone, Default)]
220pub struct ModuleOptionsContext {
221 pub ecmascript: EcmascriptOptionsContext,
222 pub css: CssOptionsContext,
223
224 pub enable_postcss_transform: Option<ResolvedVc<PostCssTransformOptions>>,
225 pub enable_webpack_loaders: Option<ResolvedVc<WebpackLoadersOptions>>,
226 pub enable_mdx: bool,
229 pub enable_mdx_rs: Option<ResolvedVc<MdxTransformOptions>>,
230
231 pub environment: Option<ResolvedVc<Environment>>,
232 pub execution_context: Option<ResolvedVc<ExecutionContext>>,
233 pub side_effect_free_packages: Option<ResolvedVc<Glob>>,
234 pub tree_shaking_mode: Option<TreeShakingMode>,
235
236 pub static_url_tag: Option<RcStr>,
237
238 pub enable_externals_tracing: Option<ResolvedVc<ExternalsTracingOptions>>,
241
242 pub keep_last_successful_parse: bool,
246
247 pub module_rules: Vec<ModuleRule>,
249 pub rules: Vec<(ContextCondition, ResolvedVc<ModuleOptionsContext>)>,
252
253 pub analyze_mode: AnalyzeMode,
256
257 pub placeholder_for_future_extensions: (),
258}
259
260#[turbo_tasks::value(shared)]
261#[derive(Clone, Default)]
262pub struct EcmascriptOptionsContext {
263 pub enable_typeof_window_inlining: Option<TypeofWindow>,
267 pub enable_jsx: Option<ResolvedVc<JsxTransformOptions>>,
268 pub enable_types: bool,
271 pub enable_typescript_transform: Option<ResolvedVc<TypescriptTransformOptions>>,
272 pub enable_decorators: Option<ResolvedVc<DecoratorsOptions>>,
273 pub esm_url_rewrite_behavior: Option<UrlRewriteBehavior>,
274 pub import_externals: bool,
277 pub ignore_dynamic_requests: bool,
281 pub source_maps: SourceMapsType,
283
284 pub enable_exports_info_inlining: bool,
286
287 pub enable_import_as_bytes: bool,
289
290 pub enable_import_as_text: bool,
292
293 pub inline_helpers: bool,
295
296 pub infer_module_side_effects: bool,
298
299 pub placeholder_for_future_extensions: (),
300}
301
302#[turbo_tasks::value(shared)]
303#[derive(Clone, Default)]
304pub struct CssOptionsContext {
305 pub enable_raw_css: bool,
311
312 pub source_maps: SourceMapsType,
314
315 pub module_css_condition: Option<RuleCondition>,
319
320 pub lightningcss_features: turbopack_css::LightningCssFeatureFlags,
322
323 pub placeholder_for_future_extensions: (),
324}
325
326#[turbo_tasks::value_impl]
327impl ValueDefault for ModuleOptionsContext {
328 #[turbo_tasks::function]
329 fn value_default() -> Vc<Self> {
330 Self::cell(Default::default())
331 }
332}
333
334#[turbo_tasks::function]
335pub async fn side_effect_free_packages_glob(
336 side_effect_free_packages: ResolvedVc<Vec<RcStr>>,
337) -> Result<Vc<Glob>> {
338 let side_effect_free_packages = &*side_effect_free_packages.await?;
339 if side_effect_free_packages.is_empty() {
340 return Ok(Glob::new(rcstr!(""), GlobOptions::default()));
341 }
342
343 let mut globs = String::new();
344 globs.push_str("**/node_modules/{");
345 globs.push_str(&side_effect_free_packages.join(","));
346 globs.push_str("}/**");
347
348 Ok(Glob::new(globs.into(), GlobOptions::default()))
349}