Webpack for WordPress, Part 1: Adding Webpack to your WordPress theme

Asset bundlers are an important part of any modern front-end workflow. With the ubiquity of CSS pre-processors and JS-centric apps, UX developers need a simple but customizable solution for compiling, minifying, linting, and optimizing bundled source files. Past alternatives for most people probably included GUI apps like CodeKit or task runners like Grunt or Gulp. Since 2016 however, Webpack has emerged as one of the most powerful, extensible and popular asset bundlers.

webpack and WordPress logos

Webpack comes with features like minification and code splitting out of the box. This makes it an appealing choice for WordPress theme developers who want to keep their enqueued assets lean. This tutorial will walk you through the basics of how to add webpack to your next theme and customize the config. (To just view a diff of the changes outlined here, check out this pull request.)

1. Start with a copy of Underscores

For this tutorial we’re going to use a copy of underscores, a bare-bones starter theme from Automattic. You can clone underscores from the Automattic GitHub repo and do a find & replace to update the project namespaces, or you can download a copy from underscores.me, and select the “_sassify!” option behind the “Advanced Options” toggle.

2. Prerequisites: Node.js & NPM

Ensure you have up to date versions of Node.js and npm installed. Most front-end developers probably took care of this when they set up their dev environment, but for those of you who are new to the command line, you’ll want to download an installer here. If you’ve completed this step successfully, you should see results similar to these in your terminal:

$ node -v
v8.11.2
$ npm -v
5.6.0

3. Add a package.json file

To work with npm and keep your project dependencies organized, you’ll want to add a package.json file in the root directory of your project. You can run npm init and follow the prompts, use the boilerplate generated by npm init -y, or just copy this basic example of a filled out starter package:

{
  "name": "wpwp",
  "version": "1.0.0",
  "description": "Webpack for WordPress",
  "dependencies": {},
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ian-pvd/wpwp.git"
  },
  "keywords": [
    "webpack",
    "wordpress"
  ],
  "author": "ian_pvd",
  "license": "GPL-2.0",
  "bugs": {
    "url": "https://github.com/ian-pvd/wpwp/issues"
  },
  "homepage": "https://github.com/ian-pvd/wpwp#readme"
}

Note: When using this sample, be sure to update your project names and GitHub repo links.

We’ll also want to take this opportunity to add a Git ignore file, since we’ll be adding lots (hundreds) of node modules to the project which we don’t want to track. Just create a .gitignore dotfile in your project root, or if you have one already, be sure it includes these lines:

# Ignore Node Modules
node_modules/

4. Install Webpack as Project Dependency

You can install webpack via the command line using npm, with the following command:

npm i -D webpack

This is the shorthand equivalent of npm install webpack --save-dev which will install the latest version of webpack via npm, and then saves it to our list of dev dependencies in our package.json file.

In order to work with webpack on the command line, you’ll also need to install the webpack cli tools:

npm i -D webpack-cli

At this point you should be able to run the command npx webpack -v (yes that’s npx) and immediately see a webpack version returned. If you run this command and see a progress bar or a prompt asking you to install webpack, it wasn’t added correctly.

5. Add A Basic Webpack Config

Add a basic webpack config, defining an entry point and and an output pattern.

/**
 * WordPress Webpack Config
 */

// Webpack Dependencies
const path = require('path');

// Build Config
module.exports = {
  entry: {
    'site': './src/site/index.js'
  },
  'output': {
    filename: '[name].js',
    path: path.join(__dirname, 'dist/')
  }
}

Our entry point in this case will be named site and will point to an index.js file in ./src/site/. This syntax allows us to define scalable configurations with multiple entry points that compile unique site components (for example, one per WordPress template type) as individual bundles that can be enqueued separately.

With the multiple entry points syntax, we want to define an output filename using output patterns to ensure each bundle is unique, and in this case references the entry point name that generated it.

We’ll also need to add the entry point file itself, which for now can just be some placeholder content.

/**
 * Site Entry Point
 */

console.log('welcome to webpack');

With the config and entry point files in place, we’re ready to compile our project assets with webpack. You can test if your new webpack config file works with this command that compiles a production build:

npx webpack --mode production --config webpack.config.js

If that works, we can add the build and watch commands to our package.json file under scripts, with the following commands:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production --config webpack.config.js",
    "start": "webpack --mode development --config webpack.config.js --watch --colors"
  },

Now we can run a production build using just npm run build at the command line, or npm run start to run a watch build that recompiles unminified bundles whenever changes are detected.

Wrapping Up

This tutorial covered the basics of how to add webpack as a project dependency and set up a basic custom config file. For a simple diff view of the changes outlined here, take a look at this pull request. Keep a look out for Part 2: Loading your theme files into Webpack and compiling them.

ian.pvd

UX & WordPress developer currently based in Brooklyn, excited about open-source projects, improving journalism, web accessibly, and modern design. I write a lot of code, read a lot of news, listen to electronic music, and eat mostly tacos.