WordPress doesn't offer a built-in way to compile assets (SCSS, JS, fonts, images…), so many approaches with sometimes conflicting philosophies have emerged to solve this. Here's my go-to solution, inspired by my experience with the Symfony framework: WebPack Encore.
For a long time I was a fan of, successively, Grunt then Gulp, to compile my asset files in WordPress. While training on the Symfony framework a few years ago, I was pleasantly surprised by how easily this issue was handled, and I set my mind on bringing this tool to WordPress.
What is WebPack?
WebPack is a proven solution for creating a single bundle for our applications.
It will handle for us:
- The ability to import modules in our JS files (we quickly forget that our previous scripts just concatenated them together…)
- Generating a single JS entry file, while keeping the ability to split our application into modules loaded conditionally
- A single loader for JS and SCSS (including Tailwind)
- The ability to extend its configuration with many libraries: SVG, PostCSS...
- Automatic autoprefixing and ES5 transpilation via Babel: quite simply, you can forget about these issues once and for all
- The ability to version our file names: no more cache-busting headaches with every update!
- But above all: the ability to install all your front-end libraries via the npm or yarn package registry
With a bit of configuration you can even add a Hot Module Reloading system.
Above all, in my opinion, it's an essential prerequisite for finally doing away with jQuery on your sites and, at last, doing modern front-end work:
That said, one of WebPack's drawbacks, in my opinion, is that it's not easy to get into for anyone who has never used it, and just looking at its documentation makes it seem like a discipline of its own. This is where Symfony Encore comes to help us.
What is WebPack Encore and why use it?
Symfony Encore is a wrapper around WebPack's configuration. It greatly simplifies the configuration by adding a layer of abstraction on top of it.
And truth be told, it doesn't do anything more: the configuration produced by Encore could technically be written by hand… The advantage here is that everything is almost ready right after install, and the main features have been wrapped in named functions!
So, with a single line of configuration you'll be able to:
-
Fix all your jQuery problems by bundling it into every module by default (if you've ever pulled your hair out over the
jQuery is not definederror, you know what I'm talking about…) - Add a unit testing solution (like Jest) to your WordPress application
- Enable TypeScript support (yes, doing TypeScript in WordPress becomes child's play!)
- The ability at any time to extend this configuration with a regular WebPack object
It's a tool originally developed by the Symfony team, and built into the framework of the same name. But like each of their modules (called bundles), it's usable independently: so it's possible to integrate it into any kind of project, including a WordPress site.
Setting up WebPack Encore on WordPress
1. Prerequisites
WebPack is a nodeJS command-line tool, so we're going to need to use the terminal with nodeJS and npm installed (I explain in an article how to set up your workflow).
If reading the words "command line" scared you, don't run away! It's simpler than you think, really. I invite you to read this article: STOP being scared of the command line.
2. Installing via npm or Yarn
Ideally, make sure you're using the right version of nodeJS, ideally version 16 which is in Long Term Support (LTS): to me, that's the one that will give you the best compatibility with the libraries you plan on using. My article on How to Easily Switch nodeJS Versions can help you out!
We'll start by installing the library via our favorite Package Manager (NPM or Yarn):
I generally recommend using Yarn for speed reasons, but what matters most is sticking with whichever one is already in place on your project.
3. A bit of configuration…
We're going to need to create a small configuration file for WebPack. This is what will contain all the instructions WebPack needs to run when we start the compilation:
4. Generating our assets
This is where the magic happens! We're going to be able to test our configuration by running this command:
If everything goes well, the script should end with a nice green message telling you your files have been generated in the folder specified as outputPath, here /dist.
With the dev command, your assets have been generated in development mode : it'll be easy to debug thanks to the .map files. However, to push our files live it's better to generate them with the following command:
Finally, here's the magic command that will let you, in development mode, automatically regenerate your assets on the fly:
In practice, you run this command at the start of your work session and work on your source files as usual: like any watcher, it will automatically update your /dist folder every time one of your source files changes or let you know if errors in your code are preventing compilation. Once you try it, you'll never go back.
5. Loading assets into the application
Unlike some implementations I've come across, I don't use a loader for the PHP side, finding it simpler to load the app.js file directly using the classic method:
That said, if you'd also like to automate enqueueing assets in the WordPress theme (to enable file name versioning, for example), you can take inspiration from this loader built by a third-party developer: https://github.com/PhatKoala/webpack-encore-for-wordpress/blob/master/webpack-encore.php
6. Which files should I version with GIT?
Make sure to add the node_modules folder to your .gitignore file at the root of your project. This way, it won't be versioned along with the rest of your files.
Ideally, the following files should be committed along with the rest of your project:
-
The configuration file
webpack.config.json -
The
package.jsonandpackage-lock.jsonfiles - Your assets' source files
I can only encourage you to not version the dist folder containing your generated files, and to compile it on the fly during your deployments. (We'll cover together, in an upcoming article, all the solutions that can be used for this)
Why not compile the "dist" folder inside the theme?
Reading this configuration, you might be wondering why I place my compiled files at the root of my site rather than inside the theme, as is usually the practice.
I'm not a fan of compiling my files inside the WordPress theme, and prefer a dist/ folder placed at the root of the project. For a few different reasons:
- I want to keep the ability to compile files coming from plugins and child themes into my main file, to improve my site's performance
- I like having clean URLs for my assets and being able to call them without needing to know my theme's name. This also limits WordPress footprints along the way.
- It makes life easier for me when configuring my deployment tool: PHPDeployer (see article)
This is a personal choice, nothing stops you from placing the dist/ folder wherever you want by adapting the code provided!
Conclusion
WebPack Encore removes a lot of the barriers to adopting WebPack in WordPress. If you want a quick setup for it, Symfony Encore is a robust, maintained and extensible solution. Told you Symfony and WordPress can get along just fine :P
Going further with WebPack Encore on WordPress
I obviously invite you to check out the WebPack and Encore documentation to extend their possibilities:
- Using TypeScript
- Configuring Babel
- Integrating TailwindCSS
- Setting up integration tests...
Alternatives
If for whatever reason this solution doesn't satisfy you (I'd love to hear why in the comments!), I'll offer you two alternatives for using WebPack with WordPress:
- Integrating WebPack directly into Gulp (external link)
- I did the same thing with Laravel Mix, the Symfony WebPack Encore equivalent for Laravel. The configuration is simpler, but the options are, to my taste, less advanced. More on that soon!
I'm curious to know which solution won you over... For my part WebPack Encore meets all my expectations and remains my favorite!






