From d6f74be2a63789b9211a932b6a9e22be7760f577 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 15 May 2024 19:28:33 +0100 Subject: [PATCH 1/7] React: Upgrade to the new JSX transform --- package-lock.json | 2 -- packages/babel-preset-default/index.js | 13 +------------ packages/babel-preset-default/package.json | 1 - .../lib/util.js | 4 ++-- packages/interactivity/src/directives.tsx | 4 +--- packages/interactivity/src/hooks.tsx | 2 -- 6 files changed, 4 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8dbbedaf11cbf..006be0a65641af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53162,7 +53162,6 @@ "@babel/preset-env": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.16.0", - "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", @@ -68508,7 +68507,6 @@ "@babel/preset-env": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.16.0", - "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", diff --git a/packages/babel-preset-default/index.js b/packages/babel-preset-default/index.js index 40f7c31bb3c25b..45ec6473be3cbc 100644 --- a/packages/babel-preset-default/index.js +++ b/packages/babel-preset-default/index.js @@ -75,21 +75,10 @@ module.exports = ( api ) => { ], plugins: [ require.resolve( '@wordpress/warning/babel-plugin' ), - [ - require.resolve( '@wordpress/babel-plugin-import-jsx-pragma' ), - { - scopeVariable: 'createElement', - scopeVariableFrag: 'Fragment', - source: 'react', - isDefault: false, - }, - ], [ require.resolve( '@babel/plugin-transform-react-jsx' ), { - pragma: 'createElement', - pragmaFrag: 'Fragment', - useSpread: true, + runtime: 'automatic', }, ], maybeGetPluginTransformRuntime(), diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index 4b12101565b45c..438cce0f47b96b 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -35,7 +35,6 @@ "@babel/preset-env": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.16.0", - "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index 92fdcff11612ea..2d2935c661df11 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -93,9 +93,9 @@ function defaultRequestToExternalModule( request ) { const isWordPressScript = Boolean( defaultRequestToExternal( request ) ); if ( isWordPressScript ) { - throw new Error( + /*throw new Error( `Attempted to use WordPress script in a module: ${ request }, which is not supported yet.` - ); + );*/ } } diff --git a/packages/interactivity/src/directives.tsx b/packages/interactivity/src/directives.tsx index 07328df8af210b..3e106fc51a5eec 100644 --- a/packages/interactivity/src/directives.tsx +++ b/packages/interactivity/src/directives.tsx @@ -1,12 +1,10 @@ // eslint-disable-next-line eslint-comments/disable-enable-pair /* eslint-disable react-hooks/exhaustive-deps */ -/* @jsx createElement */ - /** * External dependencies */ -import { h as createElement, type RefObject } from 'preact'; +import { type RefObject } from 'preact'; import { useContext, useMemo, useRef } from 'preact/hooks'; import { deepSignal, peek, type DeepSignal } from 'deepsignal'; diff --git a/packages/interactivity/src/hooks.tsx b/packages/interactivity/src/hooks.tsx index 2dfc08a43f6fa8..e1139df0ad40d6 100644 --- a/packages/interactivity/src/hooks.tsx +++ b/packages/interactivity/src/hooks.tsx @@ -1,5 +1,3 @@ -/* @jsx createElement */ - // eslint-disable-next-line eslint-comments/disable-enable-pair /* eslint-disable react-hooks/exhaustive-deps */ From 81a249c7c709a92d65bef282d150f72fe6772862 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 15 May 2024 21:56:45 +0100 Subject: [PATCH 2/7] Extract the JSX Runtime into its own script --- lib/client-assets.php | 8 ++++++++ .../lib/util.js | 6 ++++++ tools/webpack/development.js | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/lib/client-assets.php b/lib/client-assets.php index 13884f90fb3ea5..db3bc8443eba50 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -590,6 +590,14 @@ function gutenberg_register_vendor_scripts( $scripts ) { array( 'react' ), '18' ); + + gutenberg_override_script( + $scripts, + 'react-jsx-runtime', + gutenberg_url( 'build/react-jsx-runtime/index.min.js' ), + array(), + '18' + ); } add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' ); diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index 2d2935c661df11..51b1799a34e22a 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -42,6 +42,9 @@ function defaultRequestToExternal( request ) { case 'react-dom': return 'ReactDOM'; + + case 'react/jsx-runtime': + return 'ReactJSXRuntime'; } if ( request.includes( 'react-refresh/runtime' ) ) { @@ -117,6 +120,9 @@ function defaultRequestToHandle( request ) { case 'lodash-es': return 'lodash'; + + case 'react/jsx-runtime': + return 'react-jsx-runtime'; } if ( request.includes( 'react-refresh/runtime' ) ) { diff --git a/tools/webpack/development.js b/tools/webpack/development.js index 88ac4fba42f202..d707a6d1afc2ea 100644 --- a/tools/webpack/development.js +++ b/tools/webpack/development.js @@ -46,4 +46,22 @@ module.exports = [ } ), ], }, + { + ...sharedConfig, + name: 'react-jsx-runtime', + entry: { + 'react-jsx-runtime': { + import: 'react/jsx-runtime', + library: { + name: 'ReactJSXRuntime', + type: 'window', + }, + }, + }, + plugins: [ + new DependencyExtractionWebpackPlugin( { + useDefaults: false, + } ), + ], + }, ]; From d875bc0c409abaf46ef516d55800e9ae2ea67b55 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 15 May 2024 22:11:21 +0100 Subject: [PATCH 3/7] Do not bundle react in the jsx runtime --- lib/client-assets.php | 2 +- tools/webpack/development.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index db3bc8443eba50..ef8ce0383a4726 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -595,7 +595,7 @@ function gutenberg_register_vendor_scripts( $scripts ) { $scripts, 'react-jsx-runtime', gutenberg_url( 'build/react-jsx-runtime/index.min.js' ), - array(), + array( 'react' ), '18' ); } diff --git a/tools/webpack/development.js b/tools/webpack/development.js index d707a6d1afc2ea..310116def50322 100644 --- a/tools/webpack/development.js +++ b/tools/webpack/development.js @@ -60,7 +60,18 @@ module.exports = [ }, plugins: [ new DependencyExtractionWebpackPlugin( { + injectPolyfill: false, useDefaults: false, + requestToExternal: ( request ) => { + if ( request === 'react' ) { + return 'React'; + } + }, + requestToHandle: ( request ) => { + if ( request === 'react' ) { + return 'react'; + } + }, } ), ], }, From b59dd5b5481d51690b93e9d46f474247a200fe0a Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 15 May 2024 22:17:07 +0100 Subject: [PATCH 4/7] Fix interactivity --- .../lib/util.js | 4 ++-- packages/interactivity/src/directives.tsx | 23 +++++++++---------- packages/interactivity/src/hooks.tsx | 20 ++++++++-------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index 51b1799a34e22a..907f1db782a9f6 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -96,9 +96,9 @@ function defaultRequestToExternalModule( request ) { const isWordPressScript = Boolean( defaultRequestToExternal( request ) ); if ( isWordPressScript ) { - /*throw new Error( + throw new Error( `Attempted to use WordPress script in a module: ${ request }, which is not supported yet.` - );*/ + ); } } diff --git a/packages/interactivity/src/directives.tsx b/packages/interactivity/src/directives.tsx index 3e106fc51a5eec..cfe6adc468a011 100644 --- a/packages/interactivity/src/directives.tsx +++ b/packages/interactivity/src/directives.tsx @@ -4,7 +4,7 @@ /** * External dependencies */ -import { type RefObject } from 'preact'; +import { h as createElement, type RefObject } from 'preact'; import { useContext, useMemo, useRef } from 'preact/hooks'; import { deepSignal, peek, type DeepSignal } from 'deepsignal'; @@ -231,6 +231,7 @@ export default () => { // data-wp-context directive( 'context', + // @ts-ignore-next-line ( { directives: { context }, props: { children }, @@ -260,7 +261,7 @@ export default () => { return proxifyContext( currentValue.current, inheritedValue ); }, [ defaultEntry, inheritedValue ] ); - return { children }; + return createElement( Provider, { value: contextStack }, children ); }, { priority: 5 } ); @@ -481,12 +482,10 @@ export default () => { } ) => { // Preserve the initial inner HTML. const cached = useMemo( () => innerHTML, [] ); - return ( - - ); + return createElement( Type, { + dangerouslySetInnerHTML: { __html: cached }, + ...rest, + } ); } ); @@ -549,10 +548,10 @@ export default () => { ? getEvaluate( { scope } )( eachKey[ 0 ] ) : item; - return ( - - { element.props.content } - + return createElement( + Provider, + { value: mergedContext, key }, + element.props.content ); } ); }, diff --git a/packages/interactivity/src/hooks.tsx b/packages/interactivity/src/hooks.tsx index e1139df0ad40d6..91876e627e1a3b 100644 --- a/packages/interactivity/src/hooks.tsx +++ b/packages/interactivity/src/hooks.tsx @@ -350,17 +350,15 @@ const Directives = ( { // Recursively render the wrapper for the next priority level. const children = - nextPriorityLevels.length > 0 ? ( - - ) : ( - element - ); + nextPriorityLevels.length > 0 + ? createElement( Directives, { + directives, + priorityLevels: nextPriorityLevels, + element, + originalProps, + previousScope: scope, + } ) + : element; const props = { ...originalProps, children }; const directiveArgs = { From 0ee594aaa2ca196b49c06fed7e840af0d0e864c9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 16 May 2024 08:08:00 +0100 Subject: [PATCH 5/7] Fix JSX warnings --- packages/components/src/custom-select-control/index.js | 2 +- packages/components/src/form-token-field/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/custom-select-control/index.js b/packages/components/src/custom-select-control/index.js index 46bc4f4d9a4fb1..24b3d8bdb9bd3f 100644 --- a/packages/components/src/custom-select-control/index.js +++ b/packages/components/src/custom-select-control/index.js @@ -187,10 +187,10 @@ export default function CustomSelectControl( props ) { items.map( ( item, index ) => ( // eslint-disable-next-line react/jsx-key
  • = maxLength ) From d7d8cd5b0411cfa3121e085b0b6cfc64faa80277 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 16 May 2024 09:00:24 +0100 Subject: [PATCH 6/7] Fix production build --- packages/babel-preset-default/CHANGELOG.md | 4 ++++ packages/components/CHANGELOG.md | 4 ++++ packages/scripts/CHANGELOG.md | 4 ++++ tools/webpack/development.js | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/packages/babel-preset-default/CHANGELOG.md b/packages/babel-preset-default/CHANGELOG.md index 5735008dd472dc..15ced9c9dde12c 100644 --- a/packages/babel-preset-default/CHANGELOG.md +++ b/packages/babel-preset-default/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Breaking Changes + +- Use React's automatic runtime to transform JSX ([#61692](https://github.com/WordPress/gutenberg/pull/61692)). + ## 7.42.0 (2024-05-16) ## 7.41.0 (2024-05-02) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 393c9f7e0797f1..5579894741c7c3 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Remove usage of deprecated spreading of `key` prop in JSX ([#61692](https://github.com/WordPress/gutenberg/pull/61692)). + ## 27.6.0 (2024-05-16) ### Internal diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 8bc3319e52836c..8c5aa8c623ef09 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Breaking Changes + +- Use React's automatic runtime to transform JSX ([#61692](https://github.com/WordPress/gutenberg/pull/61692)). + ## 27.9.0 (2024-05-16) ### New Features diff --git a/tools/webpack/development.js b/tools/webpack/development.js index 310116def50322..716adaccbc1b92 100644 --- a/tools/webpack/development.js +++ b/tools/webpack/development.js @@ -48,6 +48,10 @@ module.exports = [ }, { ...sharedConfig, + mode: + process.env.NODE_ENV === 'production' + ? 'production' + : 'development', name: 'react-jsx-runtime', entry: { 'react-jsx-runtime': { From 1a621fc0a54a97a254884fff9243aaa863080a1e Mon Sep 17 00:00:00 2001 From: Gerardo Date: Thu, 16 May 2024 12:42:33 +0200 Subject: [PATCH 7/7] Upgrade to the new JSX transform on Mobile --- packages/react-native-editor/babel.config.js | 19 +------------------ test/native/babel.config.js | 18 +----------------- 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/packages/react-native-editor/babel.config.js b/packages/react-native-editor/babel.config.js index 27a43df36e98b3..ae6fc3cec3ebe8 100644 --- a/packages/react-native-editor/babel.config.js +++ b/packages/react-native-editor/babel.config.js @@ -32,24 +32,7 @@ module.exports = function ( api ) { [ '@babel/plugin-transform-react-jsx', { - pragma: 'createElement', - pragmaFrag: 'Fragment', - }, - ], - ], - exclude: - /node_modules\/(react-native|@react-native-community|@react-navigation|react-native-reanimated)/, - }, - { - // Auto-add `import { createElement } from 'react';` when JSX is found. - plugins: [ - [ - '@wordpress/babel-plugin-import-jsx-pragma', - { - scopeVariable: 'createElement', - scopeVariableFrag: 'Fragment', - source: 'react', - isDefault: false, + runtime: 'automatic', }, ], ], diff --git a/test/native/babel.config.js b/test/native/babel.config.js index d7bf10b1dfbc4b..0372e9fbd0a2de 100644 --- a/test/native/babel.config.js +++ b/test/native/babel.config.js @@ -22,23 +22,7 @@ module.exports = ( api ) => { [ '@babel/plugin-transform-react-jsx', { - pragma: 'createElement', - pragmaFrag: 'Fragment', - }, - ], - ], - exclude: /node_modules\/react-native/, - }, - { - // Auto-add `import { createElement } from '@wordpress/element';` when JSX is found. - plugins: [ - [ - '../../packages/babel-plugin-import-jsx-pragma', - { - scopeVariable: 'createElement', - scopeVariableFrag: 'Fragment', - source: '@wordpress/element', - isDefault: false, + runtime: 'automatic', }, ], ],