diff --git a/app/react/src/server/framework-preset-react.ts b/app/react/src/server/framework-preset-react.ts index c2180d367dd9..a24e228da3dd 100644 --- a/app/react/src/server/framework-preset-react.ts +++ b/app/react/src/server/framework-preset-react.ts @@ -1,3 +1,4 @@ +import path from 'path'; import { TransformOptions } from '@babel/core'; import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import type { Configuration } from 'webpack'; @@ -20,13 +21,28 @@ export async function babel(config: TransformOptions, options: StorybookOptions) plugins: [require.resolve('react-refresh/babel'), ...(config.plugins || [])], }; } +const storybookReactDirName = path.dirname(require.resolve('@storybook/react/package.json')); +// TODO: improve node_modules detection +const context = storybookReactDirName.includes('node_modules') + ? path.join(storybookReactDirName, '../../') // Real life case, already in node_modules + : path.join(storybookReactDirName, '../../node_modules'); // SB Monorepo + +const hasJsxRuntime = () => { + try { + require.resolve('react/jsx-runtime', { paths: [context] }); + return true; + } catch (e) { + return false; + } +}; export async function babelDefault(config: TransformOptions) { + const presetReactOptions = hasJsxRuntime() ? { runtime: 'automatic' } : {}; return { ...config, presets: [ ...config.presets, - require.resolve('@babel/preset-react'), + [require.resolve('@babel/preset-react'), presetReactOptions], require.resolve('@babel/preset-flow'), ], plugins: [...(config.plugins || []), require.resolve('babel-plugin-add-react-displayname')],