diff --git a/packages/babel-preset-react-app/create.js b/packages/babel-preset-react-app/create.js index a617a507f2..50ad64e695 100644 --- a/packages/babel-preset-react-app/create.js +++ b/packages/babel-preset-react-app/create.js @@ -8,6 +8,15 @@ const path = require('path'); +const hasJsxRuntime = (() => { + try { + require.resolve('react/jsx-runtime.js'); + return true; + } catch (e) { + return false; + } +})(); + const validateBoolOption = (name, value, defaultValue) => { if (typeof value === 'undefined') { value = defaultValue; @@ -54,10 +63,6 @@ module.exports = function (api, opts, env) { ); } - var hasJsxRuntime = Boolean( - api.caller(caller => !!caller && caller.hasJsxRuntime) - ); - if (!isEnvDevelopment && !isEnvProduction && !isEnvTest) { throw new Error( 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + @@ -100,7 +105,7 @@ module.exports = function (api, opts, env) { // Will use the native built-in instead of trying to polyfill // behavior for any plugins that require one. ...(!hasJsxRuntime ? { useBuiltIns: true } : {}), - runtime: opts.runtime || 'classic', + runtime: hasJsxRuntime ? 'automatic' : 'classic', }, ], isTypeScriptEnabled && [require('@babel/preset-typescript').default], diff --git a/packages/eslint-config-react-app/base.js b/packages/eslint-config-react-app/base.js index 1e94b5a16c..b6acd702ea 100644 --- a/packages/eslint-config-react-app/base.js +++ b/packages/eslint-config-react-app/base.js @@ -11,6 +11,15 @@ // React App support, and is used as the `baseConfig` for `eslint-loader` // to ensure that user-provided configs don't need this boilerplate. +const hasJsxRuntime = (() => { + try { + require.resolve('react/jsx-runtime.js'); + return true; + } catch (e) { + return false; + } +})(); + module.exports = { root: true, @@ -41,8 +50,10 @@ module.exports = { }, rules: { - 'react/jsx-uses-react': 'warn', 'react/jsx-uses-vars': 'warn', - 'react/react-in-jsx-scope': 'error', + ...(!hasJsxRuntime && { + 'react/jsx-uses-react': 'warn', + 'react/react-in-jsx-scope': 'error', + }), }, }; diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index bb506bbf44..b7c5913979 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -12,7 +12,6 @@ const fs = require('fs'); const path = require('path'); const webpack = require('webpack'); const resolve = require('resolve'); -const semver = require('semver'); const PnpWebpackPlugin = require('pnp-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); @@ -34,7 +33,6 @@ const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin'); const typescriptFormatter = require('react-dev-utils/typescriptFormatter'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const react = require(require.resolve('react', { paths: [paths.appPath] })); // @remove-on-eject-begin const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // @remove-on-eject-end @@ -403,16 +401,7 @@ module.exports = function (webpackEnv) { // @remove-on-eject-begin babelrc: false, configFile: false, - presets: [ - [ - require.resolve('babel-preset-react-app'), - { - runtime: semver.gte(react.version, '17.0.0-alpha.0') - ? 'automatic' - : 'classic', - }, - ], - ], + presets: [require.resolve('babel-preset-react-app')], // Make sure we have a unique cache identifier, erring on the // side of caution. // We remove this when the user ejects because the default