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    reference_type::ReferenceType, source::Source, source_transform::SourceTransforms,
7};
8use turbopack_css::CssModuleAssetType;
9use turbopack_ecmascript::{EcmascriptInputTransforms, EcmascriptOptions};
10use turbopack_wasm::source::WebAssemblySourceType;
11
12use super::{CustomModuleType, RuleCondition, match_mode::MatchMode};
13
14#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, NonLocalValue)]
15pub struct ModuleRule {
16    condition: RuleCondition,
17    effects: Vec<ModuleRuleEffect>,
18    match_mode: MatchMode,
19}
20
21impl ModuleRule {
22    /// Creates a new module rule. Will not match internal references.
23    pub fn new(condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
24        ModuleRule {
25            condition,
26            effects,
27            match_mode: MatchMode::NonInternal,
28        }
29    }
30
31    /// Creates a new module rule. Will only match internal references.
32    pub fn new_internal(condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
33        ModuleRule {
34            condition,
35            effects,
36            match_mode: MatchMode::Internal,
37        }
38    }
39
40    /// Creates a new module rule. Will match all references.
41    pub fn new_all(condition: RuleCondition, effects: Vec<ModuleRuleEffect>) -> Self {
42        ModuleRule {
43            condition,
44            effects,
45            match_mode: MatchMode::All,
46        }
47    }
48
49    pub fn effects(&self) -> impl Iterator<Item = &ModuleRuleEffect> {
50        self.effects.iter()
51    }
52
53    pub async fn matches(
54        &self,
55        source: ResolvedVc<Box<dyn Source>>,
56        path: &FileSystemPath,
57        reference_type: &ReferenceType,
58    ) -> Result<bool> {
59        Ok(self.match_mode.matches(reference_type)
60            && self.condition.matches(source, path, reference_type).await?)
61    }
62}
63
64#[turbo_tasks::value(shared)]
65#[derive(Debug, Clone)]
66pub enum ModuleRuleEffect {
67    ModuleType(ModuleType),
68    /// Allow to extend an existing Ecmascript module rules for the additional
69    /// transforms. First argument will prepend the existing transforms, and
70    /// the second argument will append the new transforms.
71    ExtendEcmascriptTransforms {
72        prepend: ResolvedVc<EcmascriptInputTransforms>,
73        append: ResolvedVc<EcmascriptInputTransforms>,
74    },
75    SourceTransforms(ResolvedVc<SourceTransforms>),
76    Ignore,
77}
78
79#[turbo_tasks::value(serialization = "auto_for_input", shared)]
80#[derive(Hash, Debug, Copy, Clone)]
81pub enum ModuleType {
82    Ecmascript {
83        transforms: ResolvedVc<EcmascriptInputTransforms>,
84        #[turbo_tasks(trace_ignore)]
85        options: ResolvedVc<EcmascriptOptions>,
86    },
87    Typescript {
88        transforms: ResolvedVc<EcmascriptInputTransforms>,
89        // parse JSX syntax.
90        tsx: bool,
91        // follow references to imported types.
92        analyze_types: bool,
93        #[turbo_tasks(trace_ignore)]
94        options: ResolvedVc<EcmascriptOptions>,
95    },
96    TypescriptDeclaration {
97        transforms: ResolvedVc<EcmascriptInputTransforms>,
98        #[turbo_tasks(trace_ignore)]
99        options: ResolvedVc<EcmascriptOptions>,
100    },
101    Json,
102    Raw,
103    CssModule,
104    Css {
105        ty: CssModuleAssetType,
106    },
107    StaticUrlJs,
108    StaticUrlCss,
109    WebAssembly {
110        source_ty: WebAssemblySourceType,
111    },
112    Custom(ResolvedVc<Box<dyn CustomModuleType>>),
113}