oxc_transformer/jsx/options.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
use serde::Deserialize;
#[inline]
fn default_as_true() -> bool {
true
}
/// Decides which runtime to use.
///
/// Auto imports the functions that JSX transpiles to.
/// classic does not automatic import anything.
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum JsxRuntime {
Classic,
/// The default runtime is switched to automatic in Babel 8.
#[default]
Automatic,
}
impl JsxRuntime {
pub fn is_classic(self) -> bool {
self == Self::Classic
}
pub fn is_automatic(self) -> bool {
self == Self::Automatic
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
pub struct JsxOptions {
#[serde(skip)]
pub jsx_plugin: bool,
#[serde(skip)]
pub display_name_plugin: bool,
#[serde(skip)]
pub jsx_self_plugin: bool,
#[serde(skip)]
pub jsx_source_plugin: bool,
// Both Runtimes
//
/// Decides which runtime to use.
pub runtime: JsxRuntime,
/// This toggles behavior specific to development, such as adding __source and __self.
///
/// Defaults to `false`.
pub development: bool,
/// Toggles whether or not to throw an error if a XML namespaced tag name is used.
///
/// Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.
#[serde(default = "default_as_true")]
pub throw_if_namespace: bool,
/// Enables `@babel/plugin-transform-react-pure-annotations`.
///
/// It will mark top-level React method calls as pure for tree shaking.
///
/// Defaults to `true`.
#[serde(default = "default_as_true")]
pub pure: bool,
// React Automatic Runtime
//
/// Replaces the import source when importing functions.
///
/// Defaults to `react`.
#[serde(default)]
pub import_source: Option<String>,
// React Classic Runtime
//
/// Replace the function used when compiling JSX expressions.
///
/// It should be a qualified name (e.g. React.createElement) or an identifier (e.g. createElement).
///
/// Note that the @jsx React.DOM pragma has been deprecated as of React v0.12
///
/// Defaults to `React.createElement`.
#[serde(default)]
pub pragma: Option<String>,
/// Replace the component used when compiling JSX fragments. It should be a valid JSX tag name.
///
/// Defaults to `React.Fragment`.
#[serde(default)]
pub pragma_frag: Option<String>,
/// `useBuiltIns` is deprecated in Babel 8.
///
/// This value is used to skip Babel tests, and is not used in oxc.
pub use_built_ins: Option<bool>,
/// `useSpread` is deprecated in Babel 8.
///
/// This value is used to skip Babel tests, and is not used in oxc.
pub use_spread: Option<bool>,
/// Fast Refresh
pub refresh: Option<ReactRefreshOptions>,
}
impl Default for JsxOptions {
fn default() -> Self {
Self::enable()
}
}
impl JsxOptions {
pub fn conform(&mut self) {
if self.development {
self.jsx_plugin = true;
self.jsx_self_plugin = true;
self.jsx_source_plugin = true;
}
}
pub fn enable() -> Self {
Self {
jsx_plugin: true,
display_name_plugin: true,
jsx_self_plugin: false,
jsx_source_plugin: false,
runtime: JsxRuntime::default(),
development: false,
throw_if_namespace: default_as_true(),
pure: default_as_true(),
import_source: None,
pragma: None,
pragma_frag: None,
use_built_ins: None,
use_spread: None,
refresh: None,
}
}
pub fn disable() -> Self {
Self {
jsx_plugin: false,
display_name_plugin: false,
jsx_self_plugin: false,
jsx_source_plugin: false,
runtime: JsxRuntime::default(),
development: false,
throw_if_namespace: false,
pure: false,
import_source: None,
pragma: None,
pragma_frag: None,
use_built_ins: None,
use_spread: None,
refresh: None,
}
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
pub struct ReactRefreshOptions {
/// Specify the identifier of the refresh registration variable.
///
/// Defaults to `$RefreshReg$`.
#[serde(default = "default_refresh_reg")]
pub refresh_reg: String,
/// Specify the identifier of the refresh signature variable.
///
/// Defaults to `$RefreshSig$`.
#[serde(default = "default_refresh_sig")]
pub refresh_sig: String,
/// Controls whether to emit full signatures or use a more compact representation.
///
/// When set to `true`, this option causes this plugin to emit full, readable signatures
/// for React components and hooks. This can be useful for debugging and development purposes.
///
/// When set to `false` (default), the transformer will use a more compact representation.
/// Specifically, it generates a SHA-1 hash of the signature and then encodes it using Base64.
/// This process produces a deterministic, compact representation that's suitable for
/// production builds while still uniquely identifying components.
///
/// Defaults to `false`.
#[serde(default)]
pub emit_full_signatures: bool,
}
impl Default for ReactRefreshOptions {
fn default() -> Self {
Self {
refresh_reg: default_refresh_reg(),
refresh_sig: default_refresh_sig(),
emit_full_signatures: false,
}
}
}
fn default_refresh_reg() -> String {
String::from("$RefreshReg$")
}
fn default_refresh_sig() -> String {
String::from("$RefreshSig$")
}