Skip to content

Commit

Permalink
DEWP: Check for magic comments before minification (#65582)
Browse files Browse the repository at this point in the history
Look for magic wp:polyfill comments before minification.

Avoids having to configure Terser to preserve these comments, and also avoids having them in the minified JS.

Minifiers run in the processAssets hook at the
`PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE` stage. If we hook at the `PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY` stage to check for the magic comments, we don't have to worry about configuring Terser to preserve them (and won't have to have them making the output slightly larger either).

---------

Co-authored-by: anomiex <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: sirreal <[email protected]>
Co-authored-by: sgomes <[email protected]>
  • Loading branch information
5 people authored and gutenbergplugin committed Sep 25, 2024
1 parent 353c87f commit 2f96654
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/dependency-extraction-webpack-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancements

- Detection of magic comments is now done before minification ([#65582](https://github.com/WordPress/gutenberg/pull/65582)).

### Bug Fixes

- Fix a bug where cycles in dependent modules could enter infinite recursion ([#65291](https://github.com/WordPress/gutenberg/pull/65291)).
Expand Down
71 changes: 68 additions & 3 deletions packages/dependency-extraction-webpack-plugin/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ class DependencyExtractionWebpackPlugin {
compiler.hooks.thisCompilation.tap(
this.constructor.name,
( compilation ) => {
compilation.hooks.processAssets.tap(
{
name: this.constructor.name,
stage: compiler.webpack.Compilation
.PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY,
},
() => this.checkForMagicComments( compilation )
);
compilation.hooks.processAssets.tap(
{
name: this.constructor.name,
Expand All @@ -174,6 +182,60 @@ class DependencyExtractionWebpackPlugin {
);
}

/**
* Check for magic comments before minification, so minification doesn't have to preserve them.
* @param {webpack.Compilation} compilation
*/
checkForMagicComments( compilation ) {
// Accumulate all entrypoint chunks, some of them shared
const entrypointChunks = new Set();
for ( const entrypoint of compilation.entrypoints.values() ) {
for ( const chunk of entrypoint.chunks ) {
entrypointChunks.add( chunk );
}
}

// Process each entrypoint chunk independently
for ( const chunk of entrypointChunks ) {
const chunkFiles = Array.from( chunk.files );

const jsExtensionRegExp = this.useModules ? /\.m?js$/i : /\.js$/i;

const chunkJSFile = chunkFiles.find( ( f ) =>
jsExtensionRegExp.test( f )
);
if ( ! chunkJSFile ) {
// There's no JS file in this chunk, no work for us. Typically a `style.css` from cache group.
continue;
}

// Prepare to look for magic comments, in order to decide whether
// `wp-polyfill` is needed.
const processContentsForMagicComments = ( content ) => {
const magicComments = [];

if ( content.includes( '/* wp:polyfill */' ) ) {
magicComments.push( 'wp-polyfill' );
}

return magicComments;
};

// Go through the assets to process the sources.
// This allows us to look for magic comments.
chunkFiles.sort().forEach( ( filename ) => {
const asset = compilation.getAsset( filename );
const content = asset.source.buffer();

const wpMagicComments =
processContentsForMagicComments( content );
compilation.updateAsset( filename, ( v ) => v, {
wpMagicComments,
} );
} );
}
}

/** @param {webpack.Compilation} compilation */
addAssets( compilation ) {
const {
Expand Down Expand Up @@ -286,8 +348,11 @@ class DependencyExtractionWebpackPlugin {

// Prepare to look for magic comments, in order to decide whether
// `wp-polyfill` is needed.
const processContentsForMagicComments = ( content ) => {
if ( content.includes( '/* wp:polyfill */' ) ) {
const handleMagicComments = ( info ) => {
if ( ! info ) {
return;
}
if ( info.includes( 'wp-polyfill' ) ) {
chunkStaticDeps.add( 'wp-polyfill' );
}
};
Expand All @@ -299,7 +364,7 @@ class DependencyExtractionWebpackPlugin {
const content = asset.source.buffer();

processContentsForHash( content );
processContentsForMagicComments( content );
handleMagicComments( asset.info.wpMagicComments );
} );

// Finalise hash.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,13 @@ exports[`DependencyExtractionWebpackPlugin modules Webpack \`polyfill-magic-comm

exports[`DependencyExtractionWebpackPlugin modules Webpack \`polyfill-magic-comment\` should produce expected output: External modules should match snapshot 1`] = `[]`;

exports[`DependencyExtractionWebpackPlugin modules Webpack \`polyfill-magic-comment-minified\` should produce expected output: Asset file 'main.asset.php' should match snapshot 1`] = `
"<?php return array('dependencies' => array('wp-polyfill'), 'version' => '31d6cfe0d16ae931b73c', 'type' => 'module');
"
`;

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`] = `
"<?php return array('dependencies' => array('@wordpress/blob'), 'version' => 'a1906cfc819b623c86f8', 'type' => 'module');
"
Expand Down Expand Up @@ -666,6 +673,13 @@ exports[`DependencyExtractionWebpackPlugin scripts Webpack \`polyfill-magic-comm

exports[`DependencyExtractionWebpackPlugin scripts Webpack \`polyfill-magic-comment\` should produce expected output: External modules should match snapshot 1`] = `[]`;

exports[`DependencyExtractionWebpackPlugin scripts Webpack \`polyfill-magic-comment-minified\` should produce expected output: Asset file 'main.asset.php' should match snapshot 1`] = `
"<?php return array('dependencies' => array('wp-polyfill'), 'version' => '31d6cfe0d16ae931b73c');
"
`;

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`] = `
"<?php return array('dependencies' => array('wp-blob'), 'version' => 'd3cda564b538b44d38ef');
"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* wp:polyfill */

// Nothing else, really.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Internal dependencies
*/
const DependencyExtractionWebpackPlugin = require( '../../..' );

module.exports = {
optimization: {
minimize: true,
},
plugins: [ new DependencyExtractionWebpackPlugin() ],
};
2 changes: 1 addition & 1 deletion tools/webpack/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const baseConfig = {
parallel: true,
terserOptions: {
output: {
comments: /(translators:|wp:polyfill)/i,
comments: /translators:/i,
},
compress: {
passes: 2,
Expand Down

1 comment on commit 2f96654

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 2f96654.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/11039451962
📝 Reported issues:

Please sign in to comment.