turbopack/module_options/
module_rule.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use turbo_rcstr::RcStr;
4use turbo_tasks::{NonLocalValue, ResolvedVc, trace::TraceRawVcs};
5use turbo_tasks_fs::FileSystemPath;
6use turbopack_core::{
7    environment::Environment, reference_type::ReferenceType, source::Source,
8    source_transform::SourceTransforms,
9};
10use turbopack_css::CssModuleAssetType;
11use turbopack_ecmascript::{EcmascriptInputTransforms, EcmascriptOptions};
12use turbopack_wasm::source::WebAssemblySourceType;
13
14use super::{CustomModuleType, RuleCondition, match_mode::MatchMode};
15
16#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, NonLocalValue)]
17pub struct ModuleRule {
18    condition: RuleCondition,
19    effects: Vec<ModuleRuleEffect>,
20    match_mode: MatchMode,
21}
22
23impl ModuleRule {
24    /// Creates a new module rule. Will not match internal references.
25    pub fn new(mut condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
26        condition.flatten();
27        ModuleRule {
28            condition,
29            effects,
30            match_mode: MatchMode::NonInternal,
31        }
32    }
33
34    /// Creates a new module rule. Will only match internal references.
35    pub fn new_internal(mut condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
36        condition.flatten();
37        ModuleRule {
38            condition,
39            effects,
40            match_mode: MatchMode::Internal,
41        }
42    }
43
44    /// Creates a new module rule. Will match all references.
45    pub fn new_all(mut condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
46        condition.flatten();
47        ModuleRule {
48            condition,
49            effects,
50            match_mode: MatchMode::All,
51        }
52    }
53
54    pub fn effects(&self) -> impl Iterator<Item = &ModuleRuleEffect> {
55        self.effects.iter()
56    }
57
58    pub async fn matches(
59        &self,
60        source: ResolvedVc<Box<dyn Source>>,
61        path: &FileSystemPath,
62        reference_type: &ReferenceType,
63    ) -> Result<bool> {
64        Ok(self.match_mode.matches(reference_type)
65            && self.condition.matches(source, path, reference_type).await?)
66    }
67}
68
69#[turbo_tasks::value(shared)]
70#[derive(Debug, Clone)]
71pub enum ModuleRuleEffect {
72    ModuleType(ModuleType),
73    /// Allow to extend an existing Ecmascript module rules for the additional
74    /// transforms
75    ExtendEcmascriptTransforms {
76        /// Transforms to run first: transpile TypeScript, decorators, ...
77        preprocess: ResolvedVc<EcmascriptInputTransforms>,
78        /// Transforms to execute on standard EcmaScript (plus JSX): styled-jsx, swc plugins, ...
79        main: ResolvedVc<EcmascriptInputTransforms>,
80        /// Transforms to run last: JSX, preset-env, scan for imports, ...
81        postprocess: ResolvedVc<EcmascriptInputTransforms>,
82    },
83    SourceTransforms(ResolvedVc<SourceTransforms>),
84    Ignore,
85}
86
87#[turbo_tasks::value(shared)]
88#[derive(Hash, Debug, Clone)]
89pub enum ModuleType {
90    Ecmascript {
91        /// Transforms to run first: transpile TypeScript, decorators, ...
92        preprocess: ResolvedVc<EcmascriptInputTransforms>,
93        /// Transforms to execute on standard EcmaScript (plus JSX): styled-jsx, swc plugins, ...
94        main: ResolvedVc<EcmascriptInputTransforms>,
95        /// Transforms to run last: JSX, preset-env, scan for imports, ...
96        postprocess: ResolvedVc<EcmascriptInputTransforms>,
97        #[turbo_tasks(trace_ignore)]
98        options: ResolvedVc<EcmascriptOptions>,
99    },
100    Typescript {
101        /// Transforms to run first: transpile TypeScript, decorators, ...
102        preprocess: ResolvedVc<EcmascriptInputTransforms>,
103        /// Transforms to execute on standard EcmaScript (plus JSX): styled-jsx, swc plugins, ...
104        main: ResolvedVc<EcmascriptInputTransforms>,
105        /// Transforms to run last: JSX, preset-env, scan for imports, ...
106        postprocess: ResolvedVc<EcmascriptInputTransforms>,
107        // parse JSX syntax.
108        tsx: bool,
109        // follow references to imported types.
110        analyze_types: bool,
111        #[turbo_tasks(trace_ignore)]
112        options: ResolvedVc<EcmascriptOptions>,
113    },
114    TypescriptDeclaration {
115        /// Transforms to run first: transpile TypeScript, decorators, ...
116        preprocess: ResolvedVc<EcmascriptInputTransforms>,
117        /// Transforms to execute on standard EcmaScript (plus JSX): styled-jsx, swc plugins, ...
118        main: ResolvedVc<EcmascriptInputTransforms>,
119        /// Transforms to run last: JSX, preset-env, scan for imports, ...
120        postprocess: ResolvedVc<EcmascriptInputTransforms>,
121        #[turbo_tasks(trace_ignore)]
122        options: ResolvedVc<EcmascriptOptions>,
123    },
124    EcmascriptExtensionless {
125        /// Transforms to run first: transpile TypeScript, decorators, ...
126        preprocess: ResolvedVc<EcmascriptInputTransforms>,
127        /// Transforms to execute on standard EcmaScript (plus JSX): styled-jsx, swc plugins, ...
128        main: ResolvedVc<EcmascriptInputTransforms>,
129        /// Transforms to run last: JSX, preset-env, scan for imports, ...
130        postprocess: ResolvedVc<EcmascriptInputTransforms>,
131        #[turbo_tasks(trace_ignore)]
132        options: ResolvedVc<EcmascriptOptions>,
133    },
134    Json,
135    Raw,
136    NodeAddon,
137    CssModule,
138    Css {
139        ty: CssModuleAssetType,
140        environment: Option<ResolvedVc<Environment>>,
141    },
142    StaticUrlJs {
143        /// The tag that is passed to ChunkingContext::asset_url
144        tag: Option<RcStr>,
145    },
146    StaticUrlCss {
147        /// The tag that is passed to ChunkingContext::asset_url
148        tag: Option<RcStr>,
149    },
150    InlinedBytesJs,
151    WebAssembly {
152        source_ty: WebAssemblySourceType,
153    },
154    Custom(ResolvedVc<Box<dyn CustomModuleType>>),
155}