diff --git a/packages/babel-helper-builder-react-jsx-experimental/src/index.js b/packages/babel-helper-builder-react-jsx-experimental/src/index.js index 2e163dc65112..2f196d8e2fde 100644 --- a/packages/babel-helper-builder-react-jsx-experimental/src/index.js +++ b/packages/babel-helper-builder-react-jsx-experimental/src/index.js @@ -138,136 +138,134 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`, Program: { enter(path, state) { - if (hasJSX(path)) { - const { file } = state; - let runtime = RUNTIME_DEFAULT; - - // For jsx mode - let source = IMPORT_SOURCE_DEFAULT; - let sourceSet = !!options.importSource; - - // For createElement mode - let pragma = PRAGMA_DEFAULT; - let pragmaFrag = PRAGMA_FRAG_DEFAULT; - let pragmaSet = !!options.pragma; - let pragmaFragSet = !!options.pragmaFrag; - - if (file.ast.comments) { - for (const comment of (file.ast.comments: Array)) { - const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec( - comment.value, - ); - if (sourceMatches) { - source = sourceMatches[1]; - sourceSet = true; - } - - const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec( - comment.value, - ); - if (runtimeMatches) { - runtime = runtimeMatches[1]; - } - - const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value); - if (jsxMatches) { - pragma = jsxMatches[1]; - pragmaSet = true; - } - const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec( - comment.value, - ); - if (jsxFragMatches) { - pragmaFrag = jsxFragMatches[1]; - pragmaFragSet = true; - } + const { file } = state; + let runtime = RUNTIME_DEFAULT; + + // For jsx mode + let source = IMPORT_SOURCE_DEFAULT; + let sourceSet = !!options.importSource; + + // For createElement mode + let pragma = PRAGMA_DEFAULT; + let pragmaFrag = PRAGMA_FRAG_DEFAULT; + let pragmaSet = !!options.pragma; + let pragmaFragSet = !!options.pragmaFrag; + + if (file.ast.comments) { + for (const comment of (file.ast.comments: Array)) { + const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec( + comment.value, + ); + if (sourceMatches) { + source = sourceMatches[1]; + sourceSet = true; } - } - state.set("@babel/plugin-react-jsx/runtime", runtime); - if (runtime === "classic") { - if (sourceSet) { - throw path.buildCodeFrameError( - `importSource cannot be set when runtime is classic.`, - ); - } - state.set( - "@babel/plugin-react-jsx/createElementIdentifier", - createIdentifierParser(pragma), + const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec( + comment.value, ); - state.set( - "@babel/plugin-react-jsx/jsxFragIdentifier", - createIdentifierParser(pragmaFrag), - ); - state.set("@babel/plugin-react-jsx/usedFragment", false); - state.set( - "@babel/plugin-react-jsx/pragmaSet", - pragma !== DEFAULT.pragma, - ); - state.set( - "@babel/plugin-react-jsx/pragmaFragSet", - pragmaFrag !== DEFAULT.pragmaFrag, + if (runtimeMatches) { + runtime = runtimeMatches[1]; + } + + const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value); + if (jsxMatches) { + pragma = jsxMatches[1]; + pragmaSet = true; + } + const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec( + comment.value, ); - } else if (runtime === "automatic") { - if (pragmaSet || pragmaFragSet) { - throw path.buildCodeFrameError( - `pragma and pragmaFrag cannot be set when runtime is automatic.`, - ); + if (jsxFragMatches) { + pragmaFrag = jsxFragMatches[1]; + pragmaFragSet = true; } + } + } - const importName = addAutoImports(path, { - ...state.opts, - source, - }); - - state.set( - "@babel/plugin-react-jsx/jsxIdentifier", - createIdentifierParser( - createIdentifierName( - path, - options.development ? "jsxDEV" : "jsx", - importName, - ), - ), + state.set("@babel/plugin-react-jsx/runtime", runtime); + if (runtime === "classic") { + if (sourceSet) { + throw path.buildCodeFrameError( + `importSource cannot be set when runtime is classic.`, ); - state.set( - "@babel/plugin-react-jsx/jsxStaticIdentifier", - createIdentifierParser( - createIdentifierName( - path, - options.development ? "jsxDEV" : "jsxs", - importName, - ), - ), + } + state.set( + "@babel/plugin-react-jsx/createElementIdentifier", + createIdentifierParser(pragma), + ); + state.set( + "@babel/plugin-react-jsx/jsxFragIdentifier", + createIdentifierParser(pragmaFrag), + ); + state.set("@babel/plugin-react-jsx/usedFragment", false); + state.set( + "@babel/plugin-react-jsx/pragmaSet", + pragma !== DEFAULT.pragma, + ); + state.set( + "@babel/plugin-react-jsx/pragmaFragSet", + pragmaFrag !== DEFAULT.pragmaFrag, + ); + } else if (runtime === "automatic") { + if (pragmaSet || pragmaFragSet) { + throw path.buildCodeFrameError( + `pragma and pragmaFrag cannot be set when runtime is automatic.`, ); + } - state.set( - "@babel/plugin-react-jsx/createElementIdentifier", - createIdentifierParser( - createIdentifierName(path, "createElement", importName), + const importName = addAutoImports(path, { + ...state.opts, + source, + }); + + state.set( + "@babel/plugin-react-jsx/jsxIdentifier", + createIdentifierParser( + createIdentifierName( + path, + options.development ? "jsxDEV" : "jsx", + importName, ), - ); - - state.set( - "@babel/plugin-react-jsx/jsxFragIdentifier", - createIdentifierParser( - createIdentifierName(path, "Fragment", importName), + ), + ); + state.set( + "@babel/plugin-react-jsx/jsxStaticIdentifier", + createIdentifierParser( + createIdentifierName( + path, + options.development ? "jsxDEV" : "jsxs", + importName, ), - ); + ), + ); - state.set( - "@babel/plugin-react-jsx/importSourceSet", - source !== DEFAULT.importSource, - ); - } else { - throw path.buildCodeFrameError( - `Runtime must be either "classic" or "automatic".`, - ); - } + state.set( + "@babel/plugin-react-jsx/createElementIdentifier", + createIdentifierParser( + createIdentifierName(path, "createElement", importName), + ), + ); - if (options.development) { - path.traverse(injectMetaPropertiesVisitor, state); - } + state.set( + "@babel/plugin-react-jsx/jsxFragIdentifier", + createIdentifierParser( + createIdentifierName(path, "Fragment", importName), + ), + ); + + state.set( + "@babel/plugin-react-jsx/importSourceSet", + source !== DEFAULT.importSource, + ); + } else { + throw path.buildCodeFrameError( + `Runtime must be either "classic" or "automatic".`, + ); + } + + if (options.development) { + path.traverse(injectMetaPropertiesVisitor, state); } }, @@ -353,18 +351,6 @@ You can set \`throwIfNamespace: false\` to bypass this warning.`, return imports; } - function hasJSX(parentPath) { - let fileHasJSX = false; - parentPath.traverse({ - "JSXElement|JSXFragment"(path) { - fileHasJSX = true; - path.stop(); - }, - }); - - return fileHasJSX; - } - function getSource(source, importName) { switch (importName) { case "Fragment": diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/input.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/input.js new file mode 100644 index 000000000000..8f34f4659447 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/input.js @@ -0,0 +1 @@ +const foo = 2; diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/options.json new file mode 100644 index 000000000000..b8505036d209 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["transform-react-jsx", { "runtime": "automatic" }], + "./plugin.js" + ] +} diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/output.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/output.js new file mode 100644 index 000000000000..7a12700836b4 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/output.js @@ -0,0 +1 @@ +const foo = /*#__PURE__*/undefined.jsx("p", {}); diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/plugin.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/plugin.js new file mode 100644 index 000000000000..008f85eda2a4 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-automatic/plugin.js @@ -0,0 +1,13 @@ +module.exports = ({ types: t }) => ({ + visitor: { + NumericLiteral(path) { + path.replaceWith( + t.jsxElement( + t.jsxOpeningElement(t.jsxIdentifier("p"), []), + t.jsxClosingElement(t.jsxIdentifier("p")), + [] + ) + ); + } + } +}); diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/input.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/input.js new file mode 100644 index 000000000000..8f34f4659447 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/input.js @@ -0,0 +1 @@ +const foo = 2; diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/options.json new file mode 100644 index 000000000000..4dba1655893c --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["transform-react-jsx", { "runtime": "classic" }], + "./plugin.js" + ] +} diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/output.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/output.js new file mode 100644 index 000000000000..b28842cb637a --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/output.js @@ -0,0 +1 @@ +const foo = /*#__PURE__*/React.createElement("p", null); diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/plugin.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/plugin.js new file mode 100644 index 000000000000..008f85eda2a4 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/regression/issue-12478-classic/plugin.js @@ -0,0 +1,13 @@ +module.exports = ({ types: t }) => ({ + visitor: { + NumericLiteral(path) { + path.replaceWith( + t.jsxElement( + t.jsxOpeningElement(t.jsxIdentifier("p"), []), + t.jsxClosingElement(t.jsxIdentifier("p")), + [] + ) + ); + } + } +});