Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centralize and Automate Plugin Asset Minification in Webpack #1718

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/php-test-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ on:
- 'tests/multisite.xml'
- 'composer.json'
- 'composer.lock'
- 'webpack.config.js'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason for adding this is that unit tests for the plugins can fail if the minified assets aren’t generated. Since Webpack is responsible for generating these assets and copying necessary libraries from node_modules to the build, it makes sense to include changes to webpack.config.js as a trigger for the unit tests.

pull_request:
# Only run if PHP-related files changed.
paths:
Expand All @@ -28,6 +29,7 @@ on:
- 'tests/multisite.xml'
- 'composer.json'
- 'composer.lock'
- 'webpack.config.js'
types:
- opened
- reopened
Expand Down
142 changes: 37 additions & 105 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,128 +35,62 @@ const sharedConfig = {
};

// Store plugins that require build process.
const pluginsWithBuild = [
'performance-lab',
'embed-optimizer',
'image-prioritizer',
'optimization-detective',
'web-worker-offloading',
];

/**
* Webpack Config: Performance Lab
*
* @param {*} env Webpack environment
* @return {Object} Webpack configuration
*/
const performanceLab = ( env ) => {
if ( env.plugin && env.plugin !== 'performance-lab' ) {
return defaultBuildConfig;
}

const pluginDir = path.resolve( __dirname, 'plugins/performance-lab' );

return {
...sharedConfig,
name: 'performance-lab',
plugins: [
new CopyWebpackPlugin( {
patterns: [
{
from: `${ pluginDir }/includes/admin/plugin-activate-ajax.js`,
to: `${ pluginDir }/includes/admin/plugin-activate-ajax.min.js`,
},
],
} ),
new WebpackBar( {
name: 'Building Performance Lab Assets',
color: '#2196f3',
} ),
],
};
};
const pluginsWithBuild = [ 'optimization-detective', 'web-worker-offloading' ];

/**
* Webpack Config: Embed Optimizer
* Webpack Config: Minify Plugin Assets
*
* @param {*} env Webpack environment
* @return {Object} Webpack configuration
*/
const embedOptimizer = ( env ) => {
if ( env.plugin && env.plugin !== 'embed-optimizer' ) {
return defaultBuildConfig;
}

const pluginDir = path.resolve( __dirname, 'plugins/embed-optimizer' );

return {
...sharedConfig,
name: 'embed-optimizer',
plugins: [
new CopyWebpackPlugin( {
patterns: [
{
from: `${ pluginDir }/detect.js`,
to: `${ pluginDir }/detect.min.js`,
},
{
from: `${ pluginDir }/lazy-load.js`,
to: `${ pluginDir }/lazy-load.min.js`,
},
],
} ),
new WebpackBar( {
name: 'Building Embed Optimizer Assets',
color: '#2196f3',
} ),
],
};
};
const minifyPluginAssets = ( env ) => {
if ( env.plugin && ! standalonePlugins.includes( env.plugin ) ) {
// eslint-disable-next-line no-console
console.error( `Plugin "${ env.plugin }" not found. Aborting.` );

/**
* Webpack Config: Image Prioritizer
*
* @param {*} env Webpack environment
* @return {Object} Webpack configuration
*/
const imagePrioritizer = ( env ) => {
if ( env.plugin && env.plugin !== 'image-prioritizer' ) {
return defaultBuildConfig;
}

const pluginDir = path.resolve( __dirname, 'plugins/image-prioritizer' );
const sourcePath = env.plugin
? path.resolve( __dirname, 'plugins', env.plugin )
: path.resolve( __dirname, 'plugins' );

return {
...sharedConfig,
name: 'image-prioritizer',
name: 'minify-plugin-assets',
plugins: [
new CopyWebpackPlugin( {
patterns: [
{
from: `${ pluginDir }/detect.js`,
to: `${ pluginDir }/detect.min.js`,
},
{
from: `${ pluginDir }/lazy-load-video.js`,
to: `${ pluginDir }/lazy-load-video.min.js`,
},
{
from: `${ pluginDir }/lazy-load-bg-image.js`,
to: `${ pluginDir }/lazy-load-bg-image.min.js`,
// NOTE: Automatically minifies JavaScript files with Terser during the copy process.
from: `${ sourcePath }/**/*.js`,
to: ( { absoluteFilename } ) =>
absoluteFilename.replace( /\.js$/, '.min.js' ),
// Exclude already-minified files and those in the build directory
globOptions: {
ignore: [ '**/build/**', '**/*.min.js' ],
},
// Prevents errors for plugins without JavaScript files.
noErrorOnMissing: true,
},
{
from: `${ pluginDir }/lazy-load-bg-image.css`,
to: `${ pluginDir }/lazy-load-bg-image.min.css`,
from: `${ sourcePath }/**/*.css`,
to: ( { absoluteFilename } ) =>
absoluteFilename.replace( /\.css$/, '.min.css' ),
transform: {
transformer: cssMinifyTransformer,
cache: false,
},
globOptions: {
ignore: [ '**/build/**', '**/*.min.css' ],
},
noErrorOnMissing: true,
},
],
} ),
new WebpackBar( {
name: 'Building Image Prioritizer Assets',
color: '#2196f3',
name: `Minifying Assets for ${ env.plugin ?? 'All Plugins' }`,
color: '#f5e0dc',
} ),
],
};
Expand Down Expand Up @@ -188,6 +122,7 @@ const optimizationDetective = ( env ) => {
{
from: `${ source }/dist/web-vitals.js`,
to: `${ destination }/build/web-vitals.js`,
// Ensures the file is copied without minification, preserving its original form.
info: { minimized: true },
},
{
Expand All @@ -198,10 +133,6 @@ const optimizationDetective = ( env ) => {
cache: false,
},
},
{
from: `${ destination }/detect.js`,
to: `${ destination }/detect.min.js`,
},
],
} ),
new WebpackBar( {
Expand Down Expand Up @@ -283,9 +214,12 @@ const buildPlugin = ( env ) => {
const buildDir = path.resolve( __dirname, 'build' );
const to = path.resolve( buildDir, env.plugin );
const from = path.resolve( __dirname, 'plugins', env.plugin );
const dependencies = pluginsWithBuild.includes( env.plugin )
? [ `${ env.plugin }` ]
: [];
// Ensures minification and the plugin's build process (if defined) run before building the plugin.
const dependencies = [ 'minify-plugin-assets' ];

if ( pluginsWithBuild.includes( env.plugin ) ) {
dependencies.push( env.plugin );
}

return {
...sharedConfig,
Expand Down Expand Up @@ -337,9 +271,7 @@ const buildPlugin = ( env ) => {
};

module.exports = [
performanceLab,
embedOptimizer,
imagePrioritizer,
minifyPluginAssets,
optimizationDetective,
webWorkerOffloading,
buildPlugin,
Expand Down
Loading