Skip to content

Webpack and Wordpress – The Missing Documentation

Tutorial

Making the move from gulp to Webpack for Wordpress development – don't do it

tldr: Webpack probably isn't the right tool for Wordpress development. It may sound like a little thing, but I just can’t go back to waiting for a page to reloads. I’ve been spoiled by browser-sync's css injection in gulp, and Webpack's hot media replacement in React development, and I just couldn’t get either to work in this environment.

Skip Straight to the Code

If you want to skip the explanation, you can view the full source code for the package file and the three build environment Webpack config files.

Why I Switched to Webpack

For the longest time, I’ve been passing the same trusty gulp config and package file from one Wordpress development project to the next. I modify it slightly here and there, and sure, maybe I’ve let it bloat a little, but it’s got all the build tools I need. It serves me well.

Recently though, I had to install OCaml on my machine, that meant I had to update Homebrew, which required me to update node. Of course gulp 3 no longer works with with the newest node so I would have to upgrade gulp which would mean I'd have to rewrite my config file and update several of my dependencies.

I was starting a new plugin development project that was going to be a bit more javascript dependent than usual. Specifically, in its reliance on external libraries. I’d been working in React on other projects and have really come to appreciate the cleanliness of module imports.

Between my dependency hell and my fondness for new toys, I figured if I was going to be rebuilding anyway, why not try it in Webpack.

Simple Build Requirements

My requirements were simple, I needed a scss compiler and post-processor, a javascript importer/concatenator for development, and I needed it to watch for changes on save and recompile and reload. Being a Wordpress project, the css and js needed to be separate files, and the page had to preview from my local webserver for development. A pretty basic requirement list, but nowhere on the internet could I find documentation on how to do this.

Webpack Build Scripts in Package File

There are three environments I need it to run in. The first is my general development mode. It’s the leanest version. It runs the aforementioned css compilation, js concatenation, and starts up a browser-sync server. Next there’s my testing mode; Here I add in backwards browser compatibility via post css and babel. And finally, the build version adds in the minification layer.

Add these "scripts" to your package.json file.

"scripts": {
  "build": "webpack --config webpack.config.prod.js",
  "start": "webpack --config webpack.config.dev.js --progress --watch",
  "test": "webpack --config webpack.config.test.js --progress --watch"
},

From here I’m just going to look at the dev file because that’s where I found the internet documentation lacking, but I’ll include all the files at the end.

Setting Up Webpack 4 Plugins to Work With Wordpress – The Missing Documentation

The missing chain of events in web documentation of how to setup Webpack 4 to work with Wordpress was as follows.

Webpack works by loading everything into Javascript and then using file type handlers to parse the content. The first thing you’ll need to do is save the css back out to a separate file after being imported into Javascript. In Webpack 4 the way to do this is by using the MiniCssExtract Plugin. Include an instance of the plugin your plugin definition.

Also in the plugin definitions, you’ll want to define the browser-sync options. In addition to watching for changes to js and css files, a line is added to define watching for changes to php files.

Finally, define the server and port number as a proxy for our php server address. Now when you run in dev mode, browser-sync will watch for changes in files and reload the browser on a change event. (small caveat, the injectChanges line is wishful thinking, I haven’t managed to get that to work).

Plugin Definitions for Your Config File

Don't forget to change yourlocalserver.dev to your local server address.

plugins: [
  new MiniCssExtractPlugin({
    filename: "css/[name].css"
    }),
    new BrowserSyncPlugin(
    // BrowserSync options
    {
      files: "**/*.php",
      // browse to http://localhost:3000/ during development
      host: "localhost",
      port: 3000,
        proxy: "http://yourlocalserver.dev/",
    },
    // plugin options
    {
      injectChanges: true,
    }
  ),
],

Here are the complete files for each of the three environments:

Enqueue Your individual CSS and JS files

The final piece is to enqueue the webpack outputs. Because this isn’t a js app we’ll have to enqueue the css and js separately.

Throw this into your Wordpress plugin's php file to enqueue the css files. Change the plugin and css file names to match your project.

If you're curious about the filetime, check out cache busting

function enqueue_styles() {
  wp_register_style(
      'my_plugin_css_file', // Handle
      plugins_url( 'my-plugin/assets/css/my-app.css', dirname( __FILE__ ) ), // file path
      null, // Dependency
      filemtime( plugin_dir_path( __DIR__ ) . 'my-plugin/assets/css/games_app.css' ) // Version: File modification time
  );
wp_enqueue_style('my_plugin_css_file');

function enqueue_scripts() {
  wp_register_script(
    'my-script', // Handle
    plugins_url( 'my-plugin/assets/js/my-app.js', dirname( __FILE__ ) ), // file path
    null, // Dependencies
    '1', // Version
    true // Enqueue the script in the footer.
  );
}
wp_enqueue_script('my-script');

Now we have a Wordpress dev environment that uses webpack to watch for changes to javascript, css (automatically compiled from scss), and php files, and automatically reloads them the browser to reflect those changes.

Further, with the testing environment, we add in legacy browser support via babble and post css browser prefixing, and in the production environment we add in all of Webpack’s concatenation, uglification, and minification features.

Final Thoughts

Webpack probably isn't the right tool for Wordpress development. It may sound like a little thing, but I just can’t go back to waiting for a page to reloads. I’ve been spoiled by browser-sync's css injection in gulp, and Webpack's hot media replacement in React development, and I just couldn’t get either to work in this environment.