From 36e38b544bd63616589ce660fb8e11b3295ccc61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Zi=C3=B3=C5=82kowski?= Date: Fri, 30 Aug 2024 13:16:36 +0200 Subject: [PATCH 1/4] Scripts: Make React Fast Refresh Work with multiple blocks --- .../lib/index.js | 11 +++++++- packages/scripts/config/webpack.config.js | 28 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/dependency-extraction-webpack-plugin/lib/index.js b/packages/dependency-extraction-webpack-plugin/lib/index.js index cf780d7370dcfc..9549f2fb4df65c 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/index.js +++ b/packages/dependency-extraction-webpack-plugin/lib/index.js @@ -337,7 +337,7 @@ class DependencyExtractionWebpackPlugin { // `RealContentHashPlugin` after minification, but it only modifies // already-produced asset filenames and the updated hash is not // available to plugins. - const { hashFunction, hashDigest, hashDigestLength } = + const { hashFunction, hashDigest, hashDigestLength, uniqueName } = compilation.outputOptions; const hashBuilder = createHash( hashFunction ); @@ -387,6 +387,15 @@ class DependencyExtractionWebpackPlugin { assetData.type = 'module'; } + if ( compilation.options?.optimization?.runtimeChunk !== false ) { + assetData.handle = + uniqueName + + '-' + + chunkJSFile + .replace( /\\/g, '/' ) + .replace( jsExtensionRegExp, '' ); + } + if ( combineAssets ) { combinedAssetsData[ chunkJSFile ] = assetData; continue; diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index f9ef7dc5b7acca..9dfb64e9245fba 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -7,7 +7,7 @@ const CopyWebpackPlugin = require( 'copy-webpack-plugin' ); const webpack = require( 'webpack' ); const browserslist = require( 'browserslist' ); const MiniCSSExtractPlugin = require( 'mini-css-extract-plugin' ); -const { basename, dirname, resolve } = require( 'path' ); +const { basename, dirname, relative, resolve, sep } = require( 'path' ); const ReactRefreshWebpackPlugin = require( '@pmmmwh/react-refresh-webpack-plugin' ); const RtlCssPlugin = require( 'rtlcss-webpack-plugin' ); const TerserPlugin = require( 'terser-webpack-plugin' ); @@ -115,6 +115,7 @@ const baseConfig = { optimization: { // Only concatenate modules in production, when not analyzing bundles. concatenateModules: isProduction && ! process.env.WP_BUNDLE_ANALYZER, + runtimeChunk: hasReactFastRefresh && 'single', splitChunks: { cacheGroups: { style: { @@ -340,6 +341,31 @@ const scriptConfig = { } } ); + if ( hasReactFastRefresh ) { + const runtimePath = relative( + dirname( absoluteFrom ), + fromProjectRoot( + getWordPressSrcDirectory() + + sep + + 'runtime.js' + ) + ); + const fields = + getBlockJsonScriptFields( blockJson ); + for ( const [ fieldName ] of Object.entries( + fields + ) ) { + blockJson[ fieldName ] = [ + `file:${ runtimePath }`, + ...( Array.isArray( + blockJson[ fieldName ] + ) + ? blockJson[ fieldName ] + : [ blockJson[ fieldName ] ] ), + ]; + } + } + return JSON.stringify( blockJson, null, 2 ); } From a0fc8e9a0a5acf2bc431588985b42a8a2efb3683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Zi=C3=B3=C5=82kowski?= Date: Mon, 2 Dec 2024 11:48:32 +0100 Subject: [PATCH 2/4] Properly pass the unique name for the build and updates test snapshots --- .../lib/index.js | 4 ++-- .../test/__snapshots__/build.js.snap | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/dependency-extraction-webpack-plugin/lib/index.js b/packages/dependency-extraction-webpack-plugin/lib/index.js index 9549f2fb4df65c..15307716ce44c9 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/index.js +++ b/packages/dependency-extraction-webpack-plugin/lib/index.js @@ -337,7 +337,7 @@ class DependencyExtractionWebpackPlugin { // `RealContentHashPlugin` after minification, but it only modifies // already-produced asset filenames and the updated hash is not // available to plugins. - const { hashFunction, hashDigest, hashDigestLength, uniqueName } = + const { hashFunction, hashDigest, hashDigestLength } = compilation.outputOptions; const hashBuilder = createHash( hashFunction ); @@ -389,7 +389,7 @@ class DependencyExtractionWebpackPlugin { if ( compilation.options?.optimization?.runtimeChunk !== false ) { assetData.handle = - uniqueName + + compilation.name + '-' + chunkJSFile .replace( /\\/g, '/' ) diff --git a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap index 8ea40b00d7c2d1..bafae8eb914867 100644 --- a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap +++ b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap @@ -265,17 +265,17 @@ exports[`DependencyExtractionWebpackPlugin modules Webpack \`polyfill-magic-comm exports[`DependencyExtractionWebpackPlugin modules Webpack \`polyfill-magic-comment-minified\` should produce expected output: External modules should match snapshot 1`] = `[]`; exports[`DependencyExtractionWebpackPlugin modules Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'a.asset.php' should match snapshot 1`] = ` -" array('@wordpress/blob'), 'version' => 'ee5ac21a1f0003d732e6', 'type' => 'module'); +" array('@wordpress/blob'), 'version' => 'ee5ac21a1f0003d732e6', 'type' => 'module', 'handle' => 'runtime-chunk-single-modules-a'); " `; exports[`DependencyExtractionWebpackPlugin modules Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'b.asset.php' should match snapshot 1`] = ` -" array('@wordpress/blob', 'lodash'), 'version' => '5b112b32c6db548c2997', 'type' => 'module'); +" array('@wordpress/blob', 'lodash'), 'version' => '5b112b32c6db548c2997', 'type' => 'module', 'handle' => 'runtime-chunk-single-modules-b'); " `; exports[`DependencyExtractionWebpackPlugin modules Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'runtime.asset.php' should match snapshot 1`] = ` -" array(), 'version' => 'b1ca4106075e0bd94f9c', 'type' => 'module'); +" array(), 'version' => 'b1ca4106075e0bd94f9c', 'type' => 'module', 'handle' => 'runtime-chunk-single-modules-runtime'); " `; @@ -681,17 +681,17 @@ exports[`DependencyExtractionWebpackPlugin scripts Webpack \`polyfill-magic-comm exports[`DependencyExtractionWebpackPlugin scripts Webpack \`polyfill-magic-comment-minified\` should produce expected output: External modules should match snapshot 1`] = `[]`; exports[`DependencyExtractionWebpackPlugin scripts Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'a.asset.php' should match snapshot 1`] = ` -" array('wp-blob'), 'version' => 'd091f1cbbf7603d6e12c'); +" array('wp-blob'), 'version' => 'd091f1cbbf7603d6e12c', 'handle' => 'runtime-chunk-single-scripts-a'); " `; exports[`DependencyExtractionWebpackPlugin scripts Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'b.asset.php' should match snapshot 1`] = ` -" array('lodash', 'wp-blob'), 'version' => '845bc6d4ffbdb9419ebd'); +" array('lodash', 'wp-blob'), 'version' => '845bc6d4ffbdb9419ebd', 'handle' => 'runtime-chunk-single-scripts-b'); " `; exports[`DependencyExtractionWebpackPlugin scripts Webpack \`runtime-chunk-single\` should produce expected output: Asset file 'runtime.asset.php' should match snapshot 1`] = ` -" array(), 'version' => '717eb779e609d175a7dd'); +" array(), 'version' => '717eb779e609d175a7dd', 'handle' => 'runtime-chunk-single-scripts-runtime'); " `; From cf97a83c58a15c8e381fa7a8175105b6142aa078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Tue, 3 Dec 2024 04:26:57 +0100 Subject: [PATCH 3/4] Apply suggestions from code review --- packages/dependency-extraction-webpack-plugin/lib/index.js | 1 + packages/scripts/config/webpack.config.js | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/dependency-extraction-webpack-plugin/lib/index.js b/packages/dependency-extraction-webpack-plugin/lib/index.js index 15307716ce44c9..8bc7cb29312161 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/index.js +++ b/packages/dependency-extraction-webpack-plugin/lib/index.js @@ -388,6 +388,7 @@ class DependencyExtractionWebpackPlugin { } if ( compilation.options?.optimization?.runtimeChunk !== false ) { + // Sets the script handle for the shared runtime file so WordPress registers it only once when using the asset file. assetData.handle = compilation.name + '-' + diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index 9dfb64e9245fba..2c3d423fcbd1e8 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -342,6 +342,7 @@ const scriptConfig = { } ); if ( hasReactFastRefresh ) { + // Prepends the file reference to the shared runtime chunk to every script type defined for the block. const runtimePath = relative( dirname( absoluteFrom ), fromProjectRoot( From 3d031a46c5c4b9c4f68c6bae4b0c8aa97aa94765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Zi=C3=B3=C5=82kowski?= Date: Tue, 3 Dec 2024 09:09:23 +0100 Subject: [PATCH 4/4] Add changelog entry --- packages/scripts/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 55143ae792ae5b..ceaa25c4ff9a09 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fix + +- Make React Fast Refresh in the `start` command work with multiple blocks ([64924](https://github.com/WordPress/gutenberg/pull/64924)). + ## 30.6.0 (2024-11-27) ## 30.5.1 (2024-11-18)