Overview

In this recipe, we’re customizing the @wordpress/scripts build process to bundle a plugin with a single custom block, a JavaScript file that registers a block variation, and a CSS file to style it. We’ll keep things neat by organizing the block code in a blocks directory and the JS/CSS in a resources directory—a clean and tasty setup for your project! 🗂️✨👨‍🍳

Setup

You can choose to either use the repository which provides a development environment or to just download the standalone plugin

Standalone

Instructions

Run the following command in a terminal of your choice from inside the plugins directory of your local WordPress installation.

Zsh
npx @wordpress/create-block customize-build-process --template @block-developer-cookbook/customize-build-process 
Zsh
cd customize-build-process  && npm run start

Finally, make sure to activate the plugin.

Repository

Instructions

Checkout the repository (skip this step if already done)

Zsh
git clone git@github.com:ryanwelcher/block-developer-cookbook.git

Install the dependencies

Zsh
npm install

Start the development environment (make sure you have Docker installed)

Zsh
npm run env start

Run the following script from the root of the repository

Zsh
npm run prep:customize-build-process 

Once the scaffold has completed completed, start the build process from inside the newly created plugin

Zsh
cd plugins/customize-build-process && npm run start

Finally, make sure to activate the plugin.

Step 1 – Changing the location of block files

After scaffolding the plugin and starting the build process will see the following message in your terminal and there are no files added to the build directory.

Zsh
Source directory "src" was not found. Please confirm there is a "src" directory in the root or the value passed to --webpack-src-dir is correct.

The scripts package expects to find block files in a src directory but in this project, you are using blocks to store those files. To address this, you need to tell scripts to use a different directory by passing the –webpack-src-dir flag to the build commands.

JSON
"build": "wp-scripts build --webpack-src-dir=blocks",
"start": "wp-scripts start --webpack-src-dir=blocks",

You have now told the scripts package to look for block files in a blocks directory instead of the default src directory.

Test this by running the build process again

Zsh
npm run start

You should see that the build has completed and now there will be files in the build directory of the plugin.

Step 2 – Adding a custom webpack file

Now that you have the block building, you need to get the custom Javascript and CSS files building.

The @wordpress/scripts package uses Webpack for its build process. Webpack is notoriously hard to configure but luckily the scripts package provides a default configuration so that you can extend it and only make the changes you need by adding them to a webpack.config.js file – create that file now in the root and paste this code into it:

JavaScript
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Export the webpack config.
module.exports = {
    ...defaultConfig,
};

This code is importing the default configuration from the scripts package and simply exporting it again.

If you ran either of the build commands now, scripts would detect this file and use it as its configuration. We’ve made no changes so everything will work as expected.

Try running npm run build to confirm that everything works as it did before.

Step 3 – Adding more entry points

In order to get your custom JS/CSS building you’ll need to add some new entry points to the webpack configuration file.

Entry points are the way to tell Webpack where to find a file you want to build.

JavaScript
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Export the webpack config.
module.exports = {
	...defaultConfig,
	entry: {
		variations: './resources/js/variations.js',
		'variation-styles': './resources/scss/variation.scss',
	},
};

Test this out by running npm run build and you’ll see that the new files are successfully output into the build directory.

But now there is an issue; the block is no longer being built. This is because you overrode the entry points for the configuration and Webpack doesn’t know where to find the blocks!

You could try adding the default configuration back in by adding this:

JavaScript
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Export the webpack config.
module.exports = {
	...defaultConfig,
	entry: {
		...defaultConfig.entry,
		variations: './resources/js/variations.js',
		'variation-styles': './resources/scss/variation.scss',
	},
};

This is a common pattern. You use the spread operator to add the contents of the entry object and then add your new ones.

This will work with any other property (you will see this later) however, the scripts package has a very cool feature built into it that can detect blocks and build them as needed.

You can re-enable this feature by calling defaultConfig.entry as a function and spreading the results.

JavaScript
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Export the webpack config.
module.exports = {
	...defaultConfig,
	entry: {
	    ...defaultConfig.entry(),
	    variations: './resources/js/variations.js',
	    'variation-styles': './resources/scss/variation.scss',
	},
};

Run the build command now to confirm that you now have both the new files and the block building into the build directory.

Step 4 – Cleaning up the files we don’t need

You may have also noticed that there is now an empty variation-style.js file in your build directory.

This is because Webpack creates a javascript file for every entry point even if it’s a CSS file!

You can clean this up by using the RemoveEmptyScriptsPlugin Webpack plugin. Normally, you would need to install this package but the scaffold has already taken care of that for you.

This plugin does exactly what the name implies, it removes empty scripts.

You will need to extend the plugins section of the Webpack config by using spread syntax like you did for entries in this case, you don’t need to call plugins as a function.

JavaScript
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Plugin to remove empty emitted scripts
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );

// Export the webpack config.
module.exports = {
	...defaultConfig,
	entry: {
		...defaultConfig.entry(),
		variations: './resources/js/variations.js',
		'variation-styles': './resources/scss/variation.scss',
	},
	plugins: [
		// Very important! Include WP's plugin config or the
		// world will cease to exist as we know it.
		...defaultConfig.plugins,
		// Removes the empty `.js` files generated by webpack but
		// sets it after WP has generated its `*.asset.php` file.
		new RemoveEmptyScriptsPlugin( {
			stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS,
		} ),
	],
};

Run the build command again and you’re done.

Bon appetit!