mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(transformer): import jsxs when children is static (#1080)
This commit is contained in:
parent
c7a04f42e7
commit
96332c85c6
2 changed files with 29 additions and 11 deletions
|
|
@ -19,6 +19,7 @@ pub struct ReactJsx<'a> {
|
|||
|
||||
imports: Vec<'a, Statement<'a>>,
|
||||
import_jsx: bool,
|
||||
import_jsxs: bool,
|
||||
import_fragment: bool,
|
||||
import_create_element: bool,
|
||||
}
|
||||
|
|
@ -69,6 +70,7 @@ impl<'a> ReactJsx<'a> {
|
|||
options,
|
||||
imports,
|
||||
import_jsx: false,
|
||||
import_jsxs: false,
|
||||
import_fragment: false,
|
||||
import_create_element: false,
|
||||
}
|
||||
|
|
@ -98,6 +100,7 @@ impl<'a> ReactJsx<'a> {
|
|||
&mut self,
|
||||
e: &JSXElementOrFragment<'a, 'b>,
|
||||
has_key_after_props_spread: bool,
|
||||
need_jsxs: bool,
|
||||
) {
|
||||
if self.options.runtime.is_classic() {
|
||||
return;
|
||||
|
|
@ -106,6 +109,7 @@ impl<'a> ReactJsx<'a> {
|
|||
JSXElementOrFragment::Element(_) if has_key_after_props_spread => {
|
||||
self.add_import_create_element();
|
||||
}
|
||||
JSXElementOrFragment::Element(_) if need_jsxs => self.add_import_jsxs(),
|
||||
JSXElementOrFragment::Element(_) => self.add_import_jsx(),
|
||||
JSXElementOrFragment::Fragment(_) => self.add_import_fragment(),
|
||||
}
|
||||
|
|
@ -118,6 +122,13 @@ impl<'a> ReactJsx<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_import_jsxs(&mut self) {
|
||||
if !self.import_jsxs {
|
||||
self.import_jsxs = true;
|
||||
self.add_import_statement("jsxs", "_jsxs", "react/jsx-runtime");
|
||||
}
|
||||
}
|
||||
|
||||
fn add_import_fragment(&mut self) {
|
||||
if !self.import_fragment {
|
||||
self.import_fragment = true;
|
||||
|
|
@ -158,7 +169,6 @@ impl<'a> ReactJsx<'a> {
|
|||
let is_classic = self.options.runtime.is_classic();
|
||||
let is_automatic = self.options.runtime.is_automatic();
|
||||
let has_key_after_props_spread = e.has_key_after_props_spread();
|
||||
let callee = self.get_create_element(has_key_after_props_spread);
|
||||
let children = e.children();
|
||||
|
||||
// TODO: compute the correct capacity for both runtimes
|
||||
|
|
@ -212,6 +222,7 @@ impl<'a> ReactJsx<'a> {
|
|||
arguments.push(Argument::Expression(null_expr));
|
||||
}
|
||||
|
||||
let mut need_jsxs = false;
|
||||
if is_automatic && !children.is_empty() {
|
||||
let key =
|
||||
self.ast.property_key_identifier(IdentifierName::new(SPAN, "children".into()));
|
||||
|
|
@ -224,6 +235,7 @@ impl<'a> ReactJsx<'a> {
|
|||
elements.push(ArrayExpressionElement::Expression(e));
|
||||
}
|
||||
}
|
||||
need_jsxs = true;
|
||||
Some(self.ast.array_expression(SPAN, elements, None))
|
||||
};
|
||||
if let Some(value) = value {
|
||||
|
|
@ -259,7 +271,8 @@ impl<'a> ReactJsx<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
self.add_import(e, has_key_after_props_spread);
|
||||
let callee = self.get_create_element(has_key_after_props_spread, need_jsxs);
|
||||
self.add_import(e, has_key_after_props_spread, need_jsxs);
|
||||
|
||||
self.ast.call_expression(SPAN, callee, arguments, false, None)
|
||||
}
|
||||
|
|
@ -269,7 +282,11 @@ impl<'a> ReactJsx<'a> {
|
|||
self.ast.identifier_reference_expression(ident)
|
||||
}
|
||||
|
||||
fn get_create_element(&mut self, has_key_after_props_spread: bool) -> Expression<'a> {
|
||||
fn get_create_element(
|
||||
&mut self,
|
||||
has_key_after_props_spread: bool,
|
||||
jsxs: bool,
|
||||
) -> Expression<'a> {
|
||||
match self.options.runtime {
|
||||
ReactJsxRuntime::Classic => {
|
||||
let object = self.get_react_references();
|
||||
|
|
@ -277,7 +294,13 @@ impl<'a> ReactJsx<'a> {
|
|||
self.ast.static_member_expression(SPAN, object, property, false)
|
||||
}
|
||||
ReactJsxRuntime::Automatic => {
|
||||
let name = if has_key_after_props_spread { "_createElement" } else { "_jsx" };
|
||||
let name = if has_key_after_props_spread {
|
||||
"_createElement"
|
||||
} else if jsxs {
|
||||
"_jsxs"
|
||||
} else {
|
||||
"_jsx"
|
||||
};
|
||||
let ident = IdentifierReference::new(SPAN, name.into());
|
||||
self.ast.identifier_reference_expression(ident)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Passed: 214/1083
|
||||
Passed: 219/1083
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-numeric-separator
|
||||
|
|
@ -804,7 +804,7 @@ Passed: 214/1083
|
|||
* regression/11061/input.mjs
|
||||
* variable-declaration/non-null-in-optional-chain/input.ts
|
||||
|
||||
# babel-plugin-transform-react-jsx (65/172)
|
||||
# babel-plugin-transform-react-jsx (70/172)
|
||||
* autoImport/after-polyfills/input.mjs
|
||||
* autoImport/after-polyfills-2/input.mjs
|
||||
* autoImport/after-polyfills-compiled-to-cjs/input.mjs
|
||||
|
|
@ -869,13 +869,10 @@ Passed: 214/1083
|
|||
* react/wraps-props-in-react-spread-for-middle-spread-attributes-babel-7/input.js
|
||||
* react-automatic/.should-properly-handle-comments-adjacent-to-children/input.js
|
||||
* react-automatic/arrow-functions/input.js
|
||||
* react-automatic/concatenates-adjacent-string-literals/input.js
|
||||
* react-automatic/does-not-add-source-self-automatic/input.mjs
|
||||
* react-automatic/dont-coerce-expression-containers/input.js
|
||||
* react-automatic/handle-fragments-with-key/input.js
|
||||
* react-automatic/handle-nonstatic-children/input.js
|
||||
* react-automatic/handle-spread-with-proto/input.js
|
||||
* react-automatic/handle-static-children/input.js
|
||||
* react-automatic/optimisation.react.constant-elements/input.js
|
||||
* react-automatic/pragma-works-with-no-space-at-the-end/input.js
|
||||
* react-automatic/should-add-quotes-es3/input.js
|
||||
|
|
@ -889,11 +886,9 @@ Passed: 214/1083
|
|||
* react-automatic/should-escape-xhtml-jsxtext/input.js
|
||||
* react-automatic/should-escape-xhtml-jsxtext-babel-7/input.js
|
||||
* react-automatic/should-handle-attributed-elements/input.js
|
||||
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
||||
* react-automatic/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
||||
* react-automatic/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
||||
* react-automatic/should-properly-handle-comments-between-props/input.js
|
||||
* react-automatic/should-properly-handle-keys/input.js
|
||||
* react-automatic/should-throw-error-namespaces-if-not-flag/input.js
|
||||
* react-automatic/should-throw-when-filter-is-specified/input.js
|
||||
* react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js
|
||||
|
|
|
|||
Loading…
Reference in a new issue