How to customize WebPack config in modern WordPress block development

I find myself continuing to dive deeper and deeper into WordPress block development, and the frustrating part is a lack of documentation. So here is a quick post on something I struggled with for a little a bit in the hopes it helps someone else.

block.json has some pretty cool features like render, style, viewScript, etc. Team this up with @wordpress/scripts to handle transpiling and the process is quite simple… until you want to add entry to a custom webpack config file to extend some capabilities.

The problem is that if the transpiler finds any block.json files it completely bypasses your root index.js file, which me and others used as the entry point. This wouldn’t be a problem if you just extend your custom webpack.config.js. This is how I was writing it when I first started.

/**
 * External Dependencies
 */
const path = require('path');

/**
 * WordPress Dependencies
 */
const defaultConfig = require('@wordpress/scripts/config/webpack.config.js');

module.exports = {
	...defaultConfig,
	entry: {
		...defaultConfig.entry,
		index: path.resolve(process.cwd(), 'src', 'index.js')
	},
};

Problem here is that running this removes index.js and index.assets.php from all your blocks that use block.json in the build directory, but why? I found that when I removed entry and transpiled again, the index.js and index.assets.php files came back. So it was something with that. It looked correct though. I used defaultConfig.entry with a spread operator like I always did because every documentation I read said to do it that way. Because defaultConfig.entry is an object, right?

Nope! It’s a function here! If you console.log(defautConfig) you’ll notice entry looks like this:

entry: [Function: getWebpackEntryPoints],

If you call that function you’ll see all the entry points in an object for your blocks. That means all you have to do in your webpack.config.js file to extend entry is change ...defaultConfig.entry to ...defaultConfig.entry() like so.

/**
 * External Dependencies
 */
const path = require('path');

/**
 * WordPress Dependencies
 */
const defaultConfig = require('@wordpress/scripts/config/webpack.config.js');

module.exports = {
	...defaultConfig,
	entry: {
		...defaultConfig.entry(),
		index: path.resolve(process.cwd(), 'src', 'index.js')
	},
};

Now everything works. I’m posting this because most documentation says to write it ...defaultConfig.entry, because entry is a JavaScript object. But since we are extending with the spread operator, we need to call the function to get the actual object.

, , ,

Comments