diff --git a/packages/babel-preset-react-app/create.js b/packages/babel-preset-react-app/create.js index 99a930ba470..8a058ecee55 100644 --- a/packages/babel-preset-react-app/create.js +++ b/packages/babel-preset-react-app/create.js @@ -93,10 +93,13 @@ module.exports = function (api, opts, env) { // Adds component stack to warning messages // Adds __self attribute to JSX which React will use for some warnings development: isEnvDevelopment || isEnvTest, + runtime: opts.runtime || 'classic', // Will use the native built-in instead of trying to polyfill // behavior for any plugins that require one. ...(opts.runtime !== 'automatic' ? { useBuiltIns: true } : {}), - runtime: opts.runtime || 'classic', + ...(opts.runtime === 'automatic' && opts.importSource != null + ? { importSource: opts.importSource } + : {}), }, ], isTypeScriptEnabled && [require('@babel/preset-typescript').default], diff --git a/packages/react-scripts/config/jest/babelTransform.js b/packages/react-scripts/config/jest/babelTransform.js index c5830153e80..0566347592d 100644 --- a/packages/react-scripts/config/jest/babelTransform.js +++ b/packages/react-scripts/config/jest/babelTransform.js @@ -22,6 +22,7 @@ const hasJsxRuntime = (() => { return false; } })(); +const jsxImportSource = process.env.JSX_IMPORT_SOURCE; module.exports = babelJest.createTransformer({ presets: [ @@ -29,6 +30,7 @@ module.exports = babelJest.createTransformer({ require.resolve('babel-preset-react-app'), { runtime: hasJsxRuntime ? 'automatic' : 'classic', + ...(jsxImportSource ? { importSource: jsxImportSource } : {}), }, ], ], diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index ba8fd0b9b56..b3d64fc1517 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -86,6 +86,7 @@ const hasJsxRuntime = (() => { return false; } })(); +const jsxImportSource = process.env.JSX_IMPORT_SOURCE; // This is the production and development configuration. // It is focused on developer experience, fast rebuilds, and a minimal bundle. @@ -414,6 +415,9 @@ module.exports = function (webpackEnv) { require.resolve('babel-preset-react-app'), { runtime: hasJsxRuntime ? 'automatic' : 'classic', + ...(jsxImportSource + ? { importSource: jsxImportSource } + : {}), }, ], ], diff --git a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js index 949f34ab7d2..fc1ad535b60 100644 --- a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js +++ b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js @@ -218,7 +218,7 @@ function verifyTypeScriptSetup() { if (appTsConfig.compilerOptions == null) { appTsConfig.compilerOptions = {}; firstTimeSetup = true; - } + } for (const option of Object.keys(compilerOptions)) { const { parsedValue, value, suggested, reason } = compilerOptions[option]; @@ -250,6 +250,27 @@ function verifyTypeScriptSetup() { } } + if (parsedCompilerOptions.jsxImportSource != null) { + if (hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta')) { + if (process.env.JSX_IMPORT_SOURCE == null) { + process.env.JSX_IMPORT_SOURCE = parsedCompilerOptions.jsxImportSource; + } + } else { + appTsConfig = immer(appTsConfig, config => { + delete config.compilerOptions.jsxImportSource; + }); + messages.push( + `${chalk.cyan( + 'compilerOptions.jsxImportSource' + )} removed (requires ${chalk.bold( + 'babel react runtime' + )} to be ${chalk.cyan.bold('automatic')} and ${chalk.bold( + 'typescript' + )} version ${chalk.cyan.bold('>=4.1.0-beta')})` + ); + } + } + // tsconfig will have the merged "include" and "exclude" by this point if (parsedTsConfig.include == null) { appTsConfig = immer(appTsConfig, config => {