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. First argument will prepend the existing transforms, and
71    /// the second argument will append the new transforms.
72    ExtendEcmascriptTransforms {
73        prepend: ResolvedVc<EcmascriptInputTransforms>,
74        append: ResolvedVc<EcmascriptInputTransforms>,
75    },
76    SourceTransforms(ResolvedVc<SourceTransforms>),
77    Ignore,
78}
79
80#[turbo_tasks::value(shared)]
81#[derive(Hash, Debug, Clone)]
82pub enum ModuleType {
83    Ecmascript {
84        transforms: ResolvedVc<EcmascriptInputTransforms>,
85        #[turbo_tasks(trace_ignore)]
86        options: ResolvedVc<EcmascriptOptions>,
87    },
88    Typescript {
89        transforms: ResolvedVc<EcmascriptInputTransforms>,
90        // parse JSX syntax.
91        tsx: bool,
92        // follow references to imported types.
93        analyze_types: bool,
94        #[turbo_tasks(trace_ignore)]
95        options: ResolvedVc<EcmascriptOptions>,
96    },
97    TypescriptDeclaration {
98        transforms: ResolvedVc<EcmascriptInputTransforms>,
99        #[turbo_tasks(trace_ignore)]
100        options: ResolvedVc<EcmascriptOptions>,
101    },
102    Json,
103    Raw,
104    CssModule,
105    Css {
106        ty: CssModuleAssetType,
107        environment: Option<ResolvedVc<Environment>>,
108    },
109    StaticUrlJs,
110    StaticUrlCss,
111    WebAssembly {
112        source_ty: WebAssemblySourceType,
113    },
114    Custom(ResolvedVc<Box<dyn CustomModuleType>>),
115}