Fix script version parameter for async chunks (#33332)

* Fix webpack script version parameter for JS chunks
* Fix webpack script version parameter for CSS chunks
This commit is contained in:
Chi-Hsuan Huang 2022-06-07 21:35:04 +08:00 committed by GitHub
parent 17d9e8072d
commit a2813267eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 83 deletions

View File

@ -1,77 +0,0 @@
const pluginName = 'AsyncChunkSrcVersionParameterPlugin';
/**
* Inspired by: https://github.com/webpack/webpack/issues/8115#issuecomment-663902035.
*
* This plugin modifies the webpack bootstrap code generated by the plugin at
* webpack/lib/web/JsonpMainTemplatePlugin.js and the CSS chunk loading code generated
* by @automattic/mini-css-extract-plugin-with-rtl.
*
* It will rename the function jsonpScriptSrc generated by that to webpackJsonpScriptSrc
* and install a new version that checks a user provided variable containing a script
* version parameter to specify in async chunk URLs.
*
* The jsonpScriptSrc override is only for webpack 4 (tested with 4.43 and 4.44).
*
* Webpack 5 has official support for this https://github.com/webpack/webpack/pull/8462
* so it won't be necessary.
*
* It will also append the ?ver parameter to CSS chunk hrefs loaded by @automattic/mini-css-extract-plugin-with-rtl.
*/
class AsyncChunkSrcVersionParameterPlugin {
_applyMainTemplate( mainTemplate ) {
// Append script version to all async JS chunks loaded with jsonpScriptSrc().
mainTemplate.hooks.localVars.tap(
// Use stage 1 to ensure this executes after webpack/lib/web/JsonpMainTemplatePlugin.js.
{ name: pluginName, stage: 1 },
( source ) => {
if ( source.includes( 'function jsonpScriptSrc' ) ) {
const modSource = source.replace(
'function jsonpScriptSrc',
'function webpackJsonpScriptSrc'
);
return `${ modSource }
function jsonpScriptSrc(chunkId) {
var src = webpackJsonpScriptSrc(chunkId);
if ( window.wcAdminAssets && window.wcAdminAssets.version ) {
src += '?ver=' + window.wcAdminAssets.version;
}
return src;
}
`;
}
return source;
}
);
// Append script version to all async CSS chunks loaded by @automattic/mini-css-extract-plugin-with-rtl.
mainTemplate.hooks.requireEnsure.tap(
// Use stage 1 to ensure this executes after @automattic/mini-css-extract-plugin-with-rtl.
{ name: pluginName, stage: 1 },
( source ) => {
if (
source.includes( '// mini-css-extract-plugin CSS loading' )
) {
return source.replace(
'linkTag.href = fullhref;',
`linkTag.href = fullhref;
if ( window.wcAdminAssets && window.wcAdminAssets.version ) {
linkTag.href += '?ver=' + window.wcAdminAssets.version;
}`
);
}
return source;
}
);
}
apply( compiler ) {
compiler.hooks.thisCompilation.tap( pluginName, ( compilation ) => {
this._applyMainTemplate( compilation.mainTemplate );
} );
}
}
module.exports = AsyncChunkSrcVersionParameterPlugin;

View File

@ -22,6 +22,25 @@ import { WcAdminPaymentsGatewaysBannerSlot } from './payments/payments-settings-
// eslint-disable-next-line no-undef,camelcase
__webpack_public_path__ = global.wcAdminAssets.path;
// Modify webpack to append the ?ver parameter to JS chunk
// https://webpack.js.org/api/module-variables/#__webpack_get_script_filename__-webpack-specific
// eslint-disable-next-line no-undef,camelcase
const oldGetScriptFileNameFn = __webpack_get_script_filename__;
// eslint-disable-next-line no-undef,camelcase
__webpack_get_script_filename__ = ( chunk ) => {
const filename = oldGetScriptFileNameFn( chunk );
return `${ filename }?ver=${ window.wcAdminAssets.version }`;
};
// Modify webpack to append the ?ver parameter to CSS chunk hrefs generated by mini-css-extract-plugin
// eslint-disable-next-line no-undef,camelcase
const oldMinCssFn = __webpack_require__.miniCssF;
// eslint-disable-next-line no-undef,camelcase
__webpack_require__.miniCssF = ( chunkId ) => {
const filename = oldMinCssFn( chunkId );
return `${ filename }?ver=${ window.wcAdminAssets.version }`;
};
const appRoot = document.getElementById( 'root' );
const embeddedRoot = document.getElementById( 'woocommerce-embedded-root' );
const settingsGroup = 'wc_admin';

View File

@ -13,9 +13,10 @@ const ForkTsCheckerWebpackPlugin = require( 'fork-ts-checker-webpack-plugin' );
/**
* Internal dependencies
*/
const AsyncChunkSrcVersionParameterPlugin = require( './chunk-src-version-param' );
const UnminifyWebpackPlugin = require( './unminify' );
const { webpackConfig: styleConfig } = require( '@woocommerce/internal-style-build' );
const {
webpackConfig: styleConfig,
} = require( '@woocommerce/internal-style-build' );
const WooCommerceDependencyExtractionWebpackPlugin = require( '../../packages/js/dependency-extraction-webpack-plugin/src/index' );
const NODE_ENV = process.env.NODE_ENV || 'development';
@ -185,10 +186,6 @@ const webpackConfig = {
startYear: 2000,
} ),
process.env.ANALYZE && new BundleAnalyzerPlugin(),
// Adds the script version parameter to the chunk URLs for cache busting
// TODO: Partially replace with __webpack_get_script_filename__ in app with Webpack 5.x.
// The CSS chunk portion will need to remain, as it originates in MiniCssExtractPlugin.
new AsyncChunkSrcVersionParameterPlugin(),
// We only want to generate unminified files in the development phase.
WC_ADMIN_PHASE === 'development' &&
// Generate unminified files to load the unminified version when `define( 'SCRIPT_DEBUG', true );` is set in wp-config.

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix the script version parameter for chunk URLs