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 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.