From fc3808ad8e5098fea98866979467eaa8d1447b0b Mon Sep 17 00:00:00 2001 From: Gunjan Jaswal Date: Tue, 30 Jun 2026 00:31:19 +0530 Subject: [PATCH 1/3] Add Inlined React Runtime check for React 19 incompatibilities Adds a static check that scans a plugin's JavaScript files for a bundled, outdated React runtime that breaks once WordPress upgrades to React 19. The primary, high-confidence signal is `Symbol.for( 'react.element' )`, which is only emitted by an inlined pre-React 19 JSX runtime (React 19 uses the `react.transitional.element` marker). The warning is suppressed when the runtime is externalized, detected via a `window.ReactJSXRuntime` reference or a `react-jsx-runtime` dependency in the sibling `*.asset.php` file. Usage of React APIs removed in React 19 (unmountComponentAtNode, findDOMNode, ReactCurrentOwner) is reported as a secondary signal. Registers the check, adds PHPUnit tests with passing/failing fixtures, and documents it in docs/checks.md and the changelog. Fixes #1356 --- docs/checks.md | 1 + .../Inlined_React_Runtime_Check.php | 236 ++++++++++++++++++ includes/Checker/Default_Check_Repository.php | 1 + readme.txt | 1 + .../index.js | 5 + .../legacy.js | 4 + .../load.php | 16 ++ .../index.asset.php | 1 + .../index.js | 5 + .../load.php | 16 ++ .../view.js | 6 + .../Inlined_React_Runtime_Check_Tests.php | 64 +++++ 12 files changed, 356 insertions(+) create mode 100644 includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/index.js create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/legacy.js create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/load.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.asset.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/load.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/view.js create mode 100644 tests/phpunit/tests/Checker/Checks/Inlined_React_Runtime_Check_Tests.php diff --git a/docs/checks.md b/docs/checks.md index d52ba1f90..1f23a1447 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -36,3 +36,4 @@ | enqueued_styles_scope | performance | Checks whether any stylesheets are loaded on all pages, which is usually not desirable and can lead to performance issues. | [Learn more](https://developer.wordpress.org/plugins/) | | enqueued_scripts_scope | performance | Checks whether any scripts are loaded on all pages, which is usually not desirable and can lead to performance issues. | [Learn more](https://developer.wordpress.org/plugins/) | | non_blocking_scripts | performance | Checks whether scripts and styles are enqueued using a recommended loading strategy. | [Learn more](https://developer.wordpress.org/plugins/) | +| inlined_react_runtime | performance | Detects a bundled, outdated React runtime that is incompatible with React 19. | [Learn more](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dependency-extraction-webpack-plugin/) | diff --git a/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php new file mode 100644 index 000000000..57a1f0737 --- /dev/null +++ b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php @@ -0,0 +1,236 @@ +look_for_inlined_jsx_runtime( $result, $file, $contents ); + $this->look_for_removed_react_apis( $result, $file, $contents ); + } + } + + /** + * Reports an inlined pre-19 JSX runtime, unless the runtime is externalized. + * + * @since 2.0.0 + * + * @param Check_Result $result The check result to amend. + * @param string $file Absolute path to the JavaScript file. + * @param string $contents Contents of the JavaScript file. + */ + private function look_for_inlined_jsx_runtime( Check_Result $result, $file, $contents ) { + // `Symbol.for( 'react.element' )` is only emitted by an inlined pre-19 JSX runtime. + $position = $this->find_first_match( '/Symbol\.for\(\s*[\'"]react\.element[\'"]\s*\)/', $contents ); + + if ( false === $position ) { + return; + } + + // Do not warn when the runtime is externalized to the copy shipped with WordPress. + if ( $this->is_jsx_runtime_externalized( $file, $contents ) ) { + return; + } + + $this->add_result_warning_for_file( + $result, + __( 'This file appears to inline the React JSX runtime instead of externalizing it. Bundled pre-React 19 runtimes break when WordPress upgrades to React 19. Use the dependency extraction webpack plugin so that "react-jsx-runtime" is loaded from WordPress instead.', 'plugin-check' ), + 'inlined_jsx_runtime', + $file, + $position['line'], + $position['column'], + 'https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dependency-extraction-webpack-plugin/', + 6 + ); + } + + /** + * Reports usage of React APIs that were removed in React 19. + * + * @since 2.0.0 + * + * @param Check_Result $result The check result to amend. + * @param string $file Absolute path to the JavaScript file. + * @param string $contents Contents of the JavaScript file. + */ + private function look_for_removed_react_apis( Check_Result $result, $file, $contents ) { + // These identifiers are React-specific and were removed in React 19. + $position = $this->find_first_match( '/\b(?:unmountComponentAtNode|findDOMNode|ReactCurrentOwner)\b/', $contents, $matched ); + + if ( false === $position ) { + return; + } + + $this->add_result_warning_for_file( + $result, + sprintf( + /* translators: %s: the removed React API name */ + __( 'This file references "%s", a React API that was removed in React 19 and will stop working once WordPress upgrades React. Update the bundled code to a React 19 compatible version.', 'plugin-check' ), + $matched + ), + 'react_removed_api', + $file, + $position['line'], + $position['column'], + 'https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dependency-extraction-webpack-plugin/', + 5 + ); + } + + /** + * Determines whether the JSX runtime is externalized rather than inlined. + * + * A build that externalizes the runtime references the global + * `window.ReactJSXRuntime`, or declares `react-jsx-runtime` as a dependency in + * its sibling `*.asset.php` file generated by the dependency extraction plugin. + * + * @since 2.0.0 + * + * @param string $file Absolute path to the JavaScript file. + * @param string $contents Contents of the JavaScript file. + * @return bool True if the runtime is externalized, false otherwise. + */ + private function is_jsx_runtime_externalized( $file, $contents ) { + if ( str_contains( $contents, 'window.ReactJSXRuntime' ) ) { + return true; + } + + $asset_file = preg_replace( '/\.js$/', '.asset.php', $file ); + + if ( is_string( $asset_file ) && $asset_file !== $file && file_exists( $asset_file ) ) { + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents + $asset_contents = file_get_contents( $asset_file ); + if ( false !== $asset_contents && str_contains( $asset_contents, 'react-jsx-runtime' ) ) { + return true; + } + } + + return false; + } + + /** + * Finds the first occurrence of a pattern and returns its line and column. + * + * @since 2.0.0 + * + * @param string $pattern The regular expression pattern to search for. + * @param string $contents The contents to search. + * @param string|null $matched Optional. Populated with the matched text, passed by reference. + * @return array|false Array with `line` and `column` keys, or false if no match was found. + */ + private function find_first_match( $pattern, $contents, &$matched = null ) { + if ( ! preg_match( $pattern, $contents, $matches, PREG_OFFSET_CAPTURE ) ) { + return false; + } + + $matched = $matches[0][0]; + $offset = $matches[0][1]; + + if ( 0 === $offset ) { + return array( + 'line' => 1, + 'column' => 1, + ); + } + + $before = substr( $contents, 0, $offset ); + $exploded = explode( PHP_EOL, $before ); + + return array( + 'line' => count( $exploded ), + 'column' => strlen( (string) end( $exploded ) ) + 1, + ); + } + + /** + * Gets the description for the check. + * + * Every check must have a short description explaining what the check does. + * + * @since 2.0.0 + * + * @return string Description. + */ + public function get_description(): string { + return __( 'Detects a bundled, outdated React runtime that is incompatible with React 19.', 'plugin-check' ); + } + + /** + * Gets the documentation URL for the check. + * + * Every check must have a URL with further information about the check. + * + * @since 2.0.0 + * + * @return string The documentation URL. + */ + public function get_documentation_url(): string { + return __( 'https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dependency-extraction-webpack-plugin/', 'plugin-check' ); + } +} diff --git a/includes/Checker/Default_Check_Repository.php b/includes/Checker/Default_Check_Repository.php index d1e5740e4..1e606b3e0 100644 --- a/includes/Checker/Default_Check_Repository.php +++ b/includes/Checker/Default_Check_Repository.php @@ -104,6 +104,7 @@ private function register_default_checks() { 'direct_file_access' => new Checks\Plugin_Repo\Direct_File_Access_Check(), 'external_admin_menu_links' => new Checks\Plugin_Repo\External_Admin_Menu_Links_Check(), 'wp_functions_compatibility' => new Checks\Plugin_Repo\WP_Functions_Compatibility_Check(), + 'inlined_react_runtime' => new Checks\Performance\Inlined_React_Runtime_Check(), ) ); diff --git a/readme.txt b/readme.txt index d0fbaf0ba..5174d2630 100644 --- a/readme.txt +++ b/readme.txt @@ -88,6 +88,7 @@ In any case, passing the checks in this tool likely helps to achieve a smooth pl = 2.0.0 = * Enhancement - Add WordPress functions compatibility check to flag usage of functions unavailable in a plugin's declared minimum WordPress version. +* Enhancement - Add Inlined React Runtime check to detect a bundled, outdated React runtime that breaks under React 19. * Enhancement - Add Write File check to detect plugins saving data in the plugin folder instead of the uploads directory or database. * Enhancement - Add batched AI false positive detection with check-specific prompts and AI model selection for WP-CLI. * Enhancement - Add CTRF export support for check results. diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/index.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/index.js new file mode 100644 index 000000000..9b713ae14 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/index.js @@ -0,0 +1,5 @@ +// Simulated build output that inlines a pre-React 19 JSX runtime. +( function () { + var element = Symbol.for( "react.element" ); + return element; +}() ); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/legacy.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/legacy.js new file mode 100644 index 000000000..2b227c233 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/legacy.js @@ -0,0 +1,4 @@ +// Simulated build output that calls a React API removed in React 19. +( function () { + ReactDOM.unmountComponentAtNode( document.getElementById( 'root' ) ); +}() ); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/load.php b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/load.php new file mode 100644 index 000000000..67b588c96 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/load.php @@ -0,0 +1,16 @@ + array('react', 'react-jsx-runtime', 'wp-element'), 'version' => 'abc123'); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js new file mode 100644 index 000000000..71860482c --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js @@ -0,0 +1,5 @@ +// Build output whose runtime is externalized via the sibling index.asset.php. +( function () { + var element = Symbol.for( "react.element" ); + return element; +}() ); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/load.php b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/load.php new file mode 100644 index 000000000..ae37963b8 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/load.php @@ -0,0 +1,16 @@ +run( $check_result ); + + $warnings = $check_result->get_warnings(); + + $this->assertNotEmpty( $warnings ); + $this->assertEmpty( $check_result->get_errors() ); + $this->assertSame( 2, $check_result->get_warning_count() ); + + $this->assertArrayHasKey( 'index.js', $warnings ); + $this->assertArrayHasKey( 'legacy.js', $warnings ); + + $this->assertSame( 'inlined_jsx_runtime', $this->get_first_code( $warnings['index.js'] ) ); + $this->assertSame( 'react_removed_api', $this->get_first_code( $warnings['legacy.js'] ) ); + } + + public function test_run_without_errors() { + $check = new Inlined_React_Runtime_Check(); + $check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-inlined-react-runtime-without-errors/load.php' ); + $check_result = new Check_Result( $check_context ); + + $check->run( $check_result ); + + $this->assertEmpty( $check_result->get_errors() ); + $this->assertEmpty( $check_result->get_warnings() ); + $this->assertSame( 0, $check_result->get_error_count() ); + $this->assertSame( 0, $check_result->get_warning_count() ); + } + + /** + * Returns the message code of the first warning reported for a file. + * + * @param array $file_warnings Warnings for a single file, keyed by line and column. + * @return string|null The message code, or null if none was found. + */ + private function get_first_code( array $file_warnings ) { + foreach ( $file_warnings as $columns ) { + foreach ( $columns as $messages ) { + if ( isset( $messages[0]['code'] ) ) { + return $messages[0]['code']; + } + } + } + + return null; + } +} From 2940c4f3199be4a8908bb1a3a7f371c85852c2f0 Mon Sep 17 00:00:00 2001 From: Gunjan Jaswal Date: Tue, 30 Jun 2026 09:56:40 +0530 Subject: [PATCH 2/3] Initialize $matched before passing it by reference PHPMD flagged $matched as an undefined variable in look_for_removed_react_apis since it was only created via the by-reference argument. Initialize it first. --- .../Checker/Checks/Performance/Inlined_React_Runtime_Check.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php index 57a1f0737..964c79627 100644 --- a/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php +++ b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php @@ -121,6 +121,7 @@ private function look_for_inlined_jsx_runtime( Check_Result $result, $file, $con */ private function look_for_removed_react_apis( Check_Result $result, $file, $contents ) { // These identifiers are React-specific and were removed in React 19. + $matched = ''; $position = $this->find_first_match( '/\b(?:unmountComponentAtNode|findDOMNode|ReactCurrentOwner)\b/', $contents, $matched ); if ( false === $position ) { From 2eb7396f41309e413f1cb11e58f9858bbaabcc39 Mon Sep 17 00:00:00 2001 From: Gunjan Jaswal Date: Sun, 12 Jul 2026 01:22:13 +0530 Subject: [PATCH 3/3] Harden inlined-runtime check against false negatives and positives Address the review feedback on the React 19 runtime check: - Stop treating a react-jsx-runtime dependency in the sibling .asset.php file as proof the runtime is externalized. The Symbol.for( 'react.element' ) marker means the file already inlines a pre-19 runtime, so a declared dependency can hide a stale or mixed build. Only an in-file window.ReactJSXRuntime reference now suppresses the warning. - Ignore the removed-API identifiers when they appear only in comments or string literals, so changelog notes and translation strings no longer produce false positives. Update the fixtures and tests to cover both cases. --- .../Inlined_React_Runtime_Check.php | 60 +++++++++++++------ .../asset-declared.asset.php} | 2 +- .../asset-declared.js | 5 ++ .../comment-only.js | 6 ++ .../index.js | 5 -- .../Inlined_React_Runtime_Check_Tests.php | 7 ++- 6 files changed, 59 insertions(+), 26 deletions(-) rename tests/phpunit/testdata/plugins/{test-plugin-inlined-react-runtime-without-errors/index.asset.php => test-plugin-inlined-react-runtime-with-errors/asset-declared.asset.php} (57%) create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.js create mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/comment-only.js delete mode 100644 tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js diff --git a/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php index 964c79627..37345a490 100644 --- a/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php +++ b/includes/Checker/Checks/Performance/Inlined_React_Runtime_Check.php @@ -94,7 +94,7 @@ private function look_for_inlined_jsx_runtime( Check_Result $result, $file, $con } // Do not warn when the runtime is externalized to the copy shipped with WordPress. - if ( $this->is_jsx_runtime_externalized( $file, $contents ) ) { + if ( $this->is_jsx_runtime_externalized( $contents ) ) { return; } @@ -120,9 +120,13 @@ private function look_for_inlined_jsx_runtime( Check_Result $result, $file, $con * @param string $contents Contents of the JavaScript file. */ private function look_for_removed_react_apis( Check_Result $result, $file, $contents ) { + // Blank out comments and string literals first, so a mention in a code + // comment, changelog entry, or translation string is not reported as usage. + $scannable = $this->blank_comments_and_strings( $contents ); + // These identifiers are React-specific and were removed in React 19. $matched = ''; - $position = $this->find_first_match( '/\b(?:unmountComponentAtNode|findDOMNode|ReactCurrentOwner)\b/', $contents, $matched ); + $position = $this->find_first_match( '/\b(?:unmountComponentAtNode|findDOMNode|ReactCurrentOwner)\b/', $scannable, $matched ); if ( false === $position ) { return; @@ -145,34 +149,52 @@ private function look_for_removed_react_apis( Check_Result $result, $file, $cont } /** - * Determines whether the JSX runtime is externalized rather than inlined. + * Determines whether the file references the externalized JSX runtime. * * A build that externalizes the runtime references the global - * `window.ReactJSXRuntime`, or declares `react-jsx-runtime` as a dependency in - * its sibling `*.asset.php` file generated by the dependency extraction plugin. + * `window.ReactJSXRuntime` shipped with WordPress. A `react-jsx-runtime` + * dependency declared in the sibling `*.asset.php` file is deliberately not + * treated as proof here: the `Symbol.for( 'react.element' )` marker means the + * file already inlines a pre-19 runtime, and a declared dependency does not + * rule out a stale or mixed build that still bundles its own copy. Trusting + * the asset file in that case would hide the exact breakage this check exists + * to surface. * * @since 2.0.0 * - * @param string $file Absolute path to the JavaScript file. * @param string $contents Contents of the JavaScript file. * @return bool True if the runtime is externalized, false otherwise. */ - private function is_jsx_runtime_externalized( $file, $contents ) { - if ( str_contains( $contents, 'window.ReactJSXRuntime' ) ) { - return true; - } + private function is_jsx_runtime_externalized( $contents ) { + return str_contains( $contents, 'window.ReactJSXRuntime' ); + } - $asset_file = preg_replace( '/\.js$/', '.asset.php', $file ); + /** + * Blanks out comments and string literals in JavaScript contents. + * + * Characters inside line comments, block comments, and single-, double-, or + * backtick-quoted strings are replaced with spaces. The length of the string + * and every newline are preserved, so match offsets still map to the correct + * line and column in the original contents. + * + * @since 2.0.0 + * + * @param string $contents Contents of the JavaScript file. + * @return string The contents with comments and string literals blanked out. + */ + private function blank_comments_and_strings( $contents ) { + $pattern = '~/\*.*?\*/|//[^\r\n]*|"(?:\\\\.|[^"\\\\])*"|\'(?:\\\\.|[^\'\\\\])*\'|`(?:\\\\.|[^`\\\\])*`~s'; - if ( is_string( $asset_file ) && $asset_file !== $file && file_exists( $asset_file ) ) { - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - $asset_contents = file_get_contents( $asset_file ); - if ( false !== $asset_contents && str_contains( $asset_contents, 'react-jsx-runtime' ) ) { - return true; - } - } + $blanked = preg_replace_callback( + $pattern, + static function ( $matches ) { + return preg_replace( '/[^\r\n]/', ' ', $matches[0] ); + }, + $contents + ); - return false; + // On a PCRE failure (e.g. backtracking limit) fall back to the raw contents. + return is_string( $blanked ) ? $blanked : $contents; } /** diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.asset.php b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.asset.php similarity index 57% rename from tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.asset.php rename to tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.asset.php index c04297576..605b75650 100644 --- a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.asset.php +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.asset.php @@ -1 +1 @@ - array('react', 'react-jsx-runtime', 'wp-element'), 'version' => 'abc123'); + array('react', 'react-jsx-runtime', 'wp-element'), 'version' => 'def456'); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.js new file mode 100644 index 000000000..017f0c3d4 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-with-errors/asset-declared.js @@ -0,0 +1,5 @@ +// Inlines a pre-19 runtime even though the sibling asset file declares react-jsx-runtime. +( function () { + var element = Symbol.for( "react.element" ); + return element; +}() ); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/comment-only.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/comment-only.js new file mode 100644 index 000000000..c0a28e1c0 --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/comment-only.js @@ -0,0 +1,6 @@ +// This build references removed React APIs only in comments and strings. +( function () { + // findDOMNode and unmountComponentAtNode were removed in React 19. + var note = 'Avoid ReactCurrentOwner; it no longer exists.'; + return note; +}() ); diff --git a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js b/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js deleted file mode 100644 index 71860482c..000000000 --- a/tests/phpunit/testdata/plugins/test-plugin-inlined-react-runtime-without-errors/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// Build output whose runtime is externalized via the sibling index.asset.php. -( function () { - var element = Symbol.for( "react.element" ); - return element; -}() ); diff --git a/tests/phpunit/tests/Checker/Checks/Inlined_React_Runtime_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Inlined_React_Runtime_Check_Tests.php index 291d59087..92416d926 100644 --- a/tests/phpunit/tests/Checker/Checks/Inlined_React_Runtime_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Inlined_React_Runtime_Check_Tests.php @@ -22,13 +22,18 @@ public function test_run_with_errors() { $this->assertNotEmpty( $warnings ); $this->assertEmpty( $check_result->get_errors() ); - $this->assertSame( 2, $check_result->get_warning_count() ); + $this->assertSame( 3, $check_result->get_warning_count() ); $this->assertArrayHasKey( 'index.js', $warnings ); $this->assertArrayHasKey( 'legacy.js', $warnings ); + $this->assertArrayHasKey( 'asset-declared.js', $warnings ); $this->assertSame( 'inlined_jsx_runtime', $this->get_first_code( $warnings['index.js'] ) ); $this->assertSame( 'react_removed_api', $this->get_first_code( $warnings['legacy.js'] ) ); + + // A declared react-jsx-runtime dependency in the sibling asset file must + // not suppress the inlined pre-19 runtime marker found in the JavaScript. + $this->assertSame( 'inlined_jsx_runtime', $this->get_first_code( $warnings['asset-declared.js'] ) ); } public function test_run_without_errors() {