turbopack/module_options/
module_rule.rs

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