Skip to main content

react_compiler/entrypoint/
plugin_options.rs

1use react_compiler_hir::environment_config::EnvironmentConfig;
2use serde::{Deserialize, Serialize};
3
4/// Target configuration for the compiler
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum CompilerTarget {
8    /// Standard React version target
9    Version(String), // "17", "18", "19"
10    /// Meta-internal target with custom runtime module
11    MetaInternal {
12        kind: String, // "donotuse_meta_internal"
13        #[serde(rename = "runtimeModule")]
14        runtime_module: String,
15    },
16}
17
18/// Gating configuration
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct GatingConfig {
21    pub source: String,
22    #[serde(rename = "importSpecifierName")]
23    pub import_specifier_name: String,
24}
25
26/// Dynamic gating configuration
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct DynamicGatingConfig {
29    pub source: String,
30}
31
32/// Serializable plugin options, pre-resolved by the JS shim.
33/// JS-only values (sources function, logger, etc.) are resolved before
34/// being sent to Rust.
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct PluginOptions {
38    // Pre-resolved by JS
39    pub should_compile: bool,
40    pub enable_reanimated: bool,
41    pub is_dev: bool,
42    pub filename: Option<String>,
43
44    // Pass-through options
45    #[serde(default = "default_compilation_mode")]
46    pub compilation_mode: String,
47    #[serde(default = "default_panic_threshold")]
48    pub panic_threshold: String,
49    #[serde(default = "default_target")]
50    pub target: CompilerTarget,
51    #[serde(default)]
52    pub gating: Option<GatingConfig>,
53    #[serde(default)]
54    pub dynamic_gating: Option<DynamicGatingConfig>,
55    #[serde(default)]
56    pub no_emit: bool,
57    #[serde(default)]
58    pub output_mode: Option<String>,
59    #[serde(default)]
60    pub eslint_suppression_rules: Option<Vec<String>>,
61    #[serde(default = "default_true")]
62    pub flow_suppressions: bool,
63    #[serde(default)]
64    pub ignore_use_no_forget: bool,
65    #[serde(default)]
66    pub custom_opt_out_directives: Option<Vec<String>>,
67    #[serde(default)]
68    pub environment: EnvironmentConfig,
69
70    /// Source code of the file being compiled (passed from Babel plugin for fast refresh hash).
71    #[serde(default, rename = "__sourceCode")]
72    pub source_code: Option<String>,
73
74    /// Enable profiling timing data collection.
75    #[serde(default, rename = "__profiling")]
76    pub profiling: bool,
77
78    /// Enable debug logging (HIR formatting after each pass).
79    /// Only set to true when a logger with debugLogIRs is configured on the JS side.
80    #[serde(default, rename = "__debug")]
81    pub debug: bool,
82}
83
84fn default_compilation_mode() -> String {
85    "infer".to_string()
86}
87
88fn default_panic_threshold() -> String {
89    "none".to_string()
90}
91
92fn default_target() -> CompilerTarget {
93    CompilerTarget::Version("19".to_string())
94}
95
96fn default_true() -> bool {
97    true
98}
99
100/// Output mode for the compiler, derived from PluginOptions.
101/// Matches the TS `compilerOutputMode` logic in Program.ts.
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub enum CompilerOutputMode {
104    Ssr,
105    Client,
106    Lint,
107}
108
109impl CompilerOutputMode {
110    pub fn from_opts(opts: &PluginOptions) -> Self {
111        match opts.output_mode.as_deref() {
112            Some("ssr") => Self::Ssr,
113            Some("lint") => Self::Lint,
114            _ if opts.no_emit => Self::Lint,
115            _ => Self::Client,
116        }
117    }
118}