We use Webpack at Human Made to power our frontend JS and SCSS compilation and refreshing. Webpack is a powerful tool, but there’s always been an important piece missing on our local builds when working on monolithic WP themes: refreshing PHP files when they are modified. There is a plethora of Webpack plugins for handling SCSS and JS files, but little to no prior art for server-side files.
When building WordPress themes, the PHP files in the theme should be almost entirely presentational and updating them should immediately reflect changes just as updating a JS or SCSS file does in most build pipelines.
While working on a recent project, I decided that I wanted to tackle this and have all types of theme files trigger hot reloading inside the browser. After some research, experimentation and lots of Googling I have a working solution that hot-reloads when PHP files are modified in our theme.
When configuring our project, I set it up using webpack-dev-server
to create our local build environment. We use the dev server to run Webpack and set it up to watch for changes to our JS, SCSS, and now PHP files as we build out the frontend of the site.
The below snippet resides in our Dev configuration and powers our PHP file refreshing.
const chokidar = require( 'chokidar' );
devServer: {
// ... other server config
/**
* Watch for changes to PHP files and reload the page when one changes.
*/
before ( app, server ) {
const files = [
"content/themes/{my-theme}/**/*.php"
];
chokidar
.watch( files, {
alwaysStat: true,
atomic: false,
followSymlinks: false,
ignoreInitial: true,
ignorePermissionErrors: true,
persistent: true,
usePolling: true
} )
.on( 'all', () => {
server.sockWrite( server.sockets, "content-changed" );
} );
},
}
}
Our Chokidar middleware start up before any other middlewares using before
, and we have a configuration and then use chokidar
, a file watch wrapper for Node, to watch for the PHP file changes. Let’s dive deeper into each bit.
const files = [
"content/themes/{my-theme}/**/*.php"
];
In the configuration section, we tell Chokidar which files to watch for changes. In our case, we run Webpack from the project root, and we only want to watch the theme files. Our new theme is the only presentational code we are running on this project, and refreshing the frontend is most useful for presentational code.
chokidar
.watch( files, {
alwaysStat: true,
atomic: false,
followSymlinks: false,
ignoreInitial: true,
ignorePermissionErrors: true,
persistent: true,
usePolling: true
} )
First, we tell Chokidar to watch our PHP files, and send in some configuration settings. There’s very little magic in this configuration, and I’d recommend looking at the Chokidar documentation for more.
.on( 'all', () => {
server.sockWrite( server.sockets, "content-changed" );
} );
On this final line, we’re telling Chokidar to alert Webpack dev server of any changes to the PHP files.