From 3cb7c0b1993155caa09b6217534f1fab7113ac1d Mon Sep 17 00:00:00 2001 From: Dunqing Date: Tue, 7 Nov 2023 18:34:15 +0800 Subject: [PATCH] feat(transformer/react-jsx): support `pragmaFrag` option (#1181) --- crates/oxc_transformer/src/react_jsx/mod.rs | 10 +++++++--- crates/oxc_transformer/src/react_jsx/options.rs | 7 +++++++ tasks/transform_conformance/babel.snap.md | 5 ++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/crates/oxc_transformer/src/react_jsx/mod.rs b/crates/oxc_transformer/src/react_jsx/mod.rs index 69222c937..c9c9f1e7c 100644 --- a/crates/oxc_transformer/src/react_jsx/mod.rs +++ b/crates/oxc_transformer/src/react_jsx/mod.rs @@ -366,9 +366,13 @@ impl<'a> ReactJsx<'a> { fn get_fragment(&mut self) -> Expression<'a> { match self.options.runtime { ReactJsxRuntime::Classic => { - let object = self.get_react_references(); - let property = IdentifierName::new(SPAN, "Fragment".into()); - self.ast.static_member_expression(SPAN, object, property, false) + if self.options.pragma_frag == "React.Fragment" { + let object = self.get_react_references(); + let property = IdentifierName::new(SPAN, "Fragment".into()); + return self.ast.static_member_expression(SPAN, object, property, false); + } + + self.get_call_expression_callee(self.options.pragma_frag.as_ref()) } ReactJsxRuntime::Automatic => { let ident = IdentifierReference::new(SPAN, "_Fragment".into()); diff --git a/crates/oxc_transformer/src/react_jsx/options.rs b/crates/oxc_transformer/src/react_jsx/options.rs index c2cde462c..2886fa03c 100644 --- a/crates/oxc_transformer/src/react_jsx/options.rs +++ b/crates/oxc_transformer/src/react_jsx/options.rs @@ -21,6 +21,9 @@ pub struct ReactJsxOptions { /// Note that the @jsx React.DOM pragma has been deprecated as of React v0.12 #[serde(default = "default_pragma")] pub pragma: Cow<'static, str>, + /// Replace the component used when compiling JSX fragments. It should be a valid JSX tag name. default to `React.Fragment` + #[serde(default = "default_pragma_frag")] + pub pragma_frag: Cow<'static, str>, } fn default_import_source() -> Cow<'static, str> { @@ -31,6 +34,10 @@ fn default_pragma() -> Cow<'static, str> { Cow::Borrowed("React.createElement") } +fn default_pragma_frag() -> Cow<'static, str> { + Cow::Borrowed("React.Fragment") +} + #[derive(Debug, Default, Clone, Copy, Deserialize)] #[serde(rename_all = "lowercase")] pub enum ReactJsxRuntime { diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index 7a6716b9f..3fbf7404a 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -1,4 +1,4 @@ -Passed: 262/1113 +Passed: 263/1113 # All Passed: * babel-plugin-transform-numeric-separator @@ -825,7 +825,7 @@ Passed: 262/1113 * regression/11061/input.mjs * variable-declaration/non-null-in-optional-chain/input.ts -# babel-plugin-transform-react-jsx (100/170) +# babel-plugin-transform-react-jsx (101/170) * autoImport/after-polyfills-compiled-to-cjs/input.mjs * autoImport/after-polyfills-script-not-supported/input.js * autoImport/auto-import-react-source-type-module/input.js @@ -884,7 +884,6 @@ Passed: 262/1113 * react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js * regression/issue-12478-automatic/input.js * regression/issue-12478-classic/input.js -* regression/issue-15353-classic/input.js * regression/pragma-frag-set-default-classic-runtime/input.js * removed-options/invalid-use-builtins-false/input.js * removed-options/invalid-use-builtins-true/input.js