Skip to content

Commit

Permalink
Reverts "Re-use common JSX element transform for <>...</>" (#15355)
Browse files Browse the repository at this point in the history
* Reverts "Re-use common JSX element transform for <>...</>"

* add a regression test

* fix Babel 8 test error

* Update fixtures (Windows)

* disable the regression test on Babel 8

Co-authored-by: Babel Bot <babel-bot@users.noreply.github.com>
  • Loading branch information
JLHwung and babel-bot committed Jan 20, 2023
1 parent 0f68471 commit 3952486
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/*#__PURE__*/babelHelpers.jsx(React.Fragment, {}, void 0, /*#__PURE__*/babelHelpers.jsx("span", {}), /*#__PURE__*/babelHelpers.jsx("div", {}));
/*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/babelHelpers.jsx("span", {}), /*#__PURE__*/babelHelpers.jsx("div", {}));
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _jsxFileName = "<CWD>/packages/babel-plugin-transform-react-jsx-development/test/fixtures/linux/auto-import-dev/input.js";
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import { createElement as _createElement } from "react";
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
var x = /*#__PURE__*/_jsxDEV(_Fragment, {
children: /*#__PURE__*/_jsxDEV("div", {
children: [/*#__PURE__*/_jsxDEV("div", {}, "1", false, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _jsxFileName = "<CWD>\\packages\\babel-plugin-transform-react-jsx-development\\test\\fixtures\\windows\\auto-import-dev-windows\\input.js";
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import { createElement as _createElement } from "react";
import { Fragment as _Fragment } from "react/jsx-dev-runtime";
var x = /*#__PURE__*/_jsxDEV(_Fragment, {
children: /*#__PURE__*/_jsxDEV("div", {
children: [/*#__PURE__*/_jsxDEV("div", {}, "1", false, {
Expand Down
97 changes: 64 additions & 33 deletions packages/babel-plugin-transform-react-jsx/src/create-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
Identifier,
JSXAttribute,
JSXElement,
JSXFragment,
JSXOpeningElement,
JSXSpreadAttribute,
MemberExpression,
Expand Down Expand Up @@ -71,6 +72,9 @@ export default function createPlugin({

throwIfNamespace = true,

// TODO (Babel 8): It should throw if this option is used with the automatic runtime
filter,

runtime: RUNTIME_DEFAULT = process.env.BABEL_8_BREAKING
? "automatic"
: development
Expand Down Expand Up @@ -276,24 +280,17 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
// },
},

JSXFragment(path, file) {
// <>...</> -> <React.Fragment>...</React.Fragment>

const frag = memberExpressionToJSX(get(file, "id/fragment")());
JSXFragment: {
exit(path, file) {
let callExpr;
if (get(file, "runtime") === "classic") {
callExpr = buildCreateElementFragmentCall(path, file);
} else {
callExpr = buildJSXFragmentCall(path, file);
}

path.replaceWith(
t.inherits(
t.jsxElement(
t.inherits(
t.jsxOpeningElement(frag, []),
path.node.openingFragment,
),
t.jsxClosingElement(t.cloneNode(frag)),
path.node.children,
),
path.node,
),
);
path.replaceWith(t.inherits(callExpr, path.node));
},
},

JSXElement: {
Expand Down Expand Up @@ -603,6 +600,56 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`,
return t.objectExpression(props);
}

// Builds JSX Fragment <></> into
// Production: React.jsx(type, arguments)
// Development: React.jsxDEV(type, { children })
function buildJSXFragmentCall(
path: NodePath<JSXFragment>,
file: PluginPass,
) {
const args = [get(file, "id/fragment")()];

const children = t.react.buildChildren(path.node);

args.push(
t.objectExpression(
children.length > 0
? [
buildChildrenProperty(
//@ts-expect-error The children here contains JSXSpreadChild,
// which will be thrown later
children,
),
]
: [],
),
);

if (development) {
args.push(
path.scope.buildUndefinedNode(),
t.booleanLiteral(children.length > 1),
);
}

return call(file, children.length > 1 ? "jsxs" : "jsx", args);
}

// Builds JSX Fragment <></> into
// React.createElement(React.Fragment, null, ...children)
function buildCreateElementFragmentCall(
path: NodePath<JSXFragment>,
file: PluginPass,
) {
if (filter && !filter(path.node, file)) return;

return call(file, "createElement", [
get(file, "id/fragment")(),
t.nullLiteral(),
...t.react.buildChildren(path.node),
]);
}

// Builds JSX into:
// Production: React.createElement(type, arguments, children)
// Development: React.createElement(type, arguments, children, source, self)
Expand Down Expand Up @@ -806,22 +853,6 @@ function toMemberExpression(id: string): Identifier | MemberExpression {
);
}

function memberExpressionToJSX(
expr: t.Node,
): t.JSXMemberExpression | t.JSXIdentifier {
switch (expr.type) {
case "Identifier":
return t.jsxIdentifier(expr.name);
case "MemberExpression":
return t.jsxMemberExpression(
memberExpressionToJSX(expr.object),
memberExpressionToJSX(expr.property) as t.JSXIdentifier,
);
default:
throw new Error("Internal error: unknown member expression type");
}
}

function makeSource(path: NodePath, state: PluginPass) {
const location = path.node.loc;
if (!location) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
import { jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
var x = /*#__PURE__*/_jsx(_Fragment, {
children: /*#__PURE__*/_jsxs("div", {
children: [/*#__PURE__*/_jsx("div", {}, "1"), /*#__PURE__*/_jsx("div", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
import { jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
var x = /*#__PURE__*/_jsx(_Fragment, {
children: /*#__PURE__*/_jsxs("div", {
children: [/*#__PURE__*/_jsx("div", {}, "1"), /*#__PURE__*/_jsx("div", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
var x = /*#__PURE__*/_jsx(_Fragment, {
children: /*#__PURE__*/_jsx("div", {})
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
/*#__PURE__*/_jsx("div", {
children: /*#__PURE__*/_jsxs(_Fragment, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<>Test</>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"BABEL_8_BREAKING": false,
"plugins": [
[
"transform-react-jsx",
{ "pragma": "m", "pragmaFrag": "'['", "runtime": "classic" }
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
m('[', null, "Test");

0 comments on commit 3952486

Please sign in to comment.