diff --git a/packages/dependency-extraction-webpack-plugin/lib/index.js b/packages/dependency-extraction-webpack-plugin/lib/index.js index 0e6f8a5fbc6ccc..57524b77153942 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/index.js +++ b/packages/dependency-extraction-webpack-plugin/lib/index.js @@ -275,7 +275,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 contentHash = chunkFiles @@ -302,6 +302,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 d8f9d356dda891..f8bca35f13f4ce 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' ); @@ -159,6 +159,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: { @@ -381,6 +382,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 ); }