Is WordPress theme folder the right place for an asset compilation setup?

Aug 14, 2019

For as long as I can remember it’s been kind of a go-to decision (at least in the WordPress dev bubble I’ve been in) to add your package.json/gulpfile.js/webpack.config.js into the WordPress theme/plugin folder like this:

my-project
└─── wp-content
     └─── themes
          └─── my-theme
               │ package.json
               │ gulpfile.js
               │ webpack.config.js
               │ etc.

Some years ago it kind of made sense. At least the projects I was doing were a lot smaller and most of the work was done inside the theme folder. So I used to open only the theme folder into my code editor.

Then, after some time, my needs started to change. Little by little.

Turning point #1

First I started to learn how to build plugins and the complexity of the projects I was building started to grow. And because I didn’t want to open up a few code editor windows and jump between them, I started to open the entire WordPress project into my code editor.

Turning point #2

I started to use PhpStorm at my work. From the perspective of the PHP linter in PhpStorm it made even more sense to open up the whole WordPress project into the PhpStorm instead of just opening up the theme folder. After indexing the whole project, PhpStorm could, for example, actually know which functions were available in that project.

Turning point #3

During this year (2019) I built my first plugin for a client project that:

  1. Was going to be distributed into a multiple WordPress installations.
  2. Had Vue.js based front-end.
  3. Had some complex CSS needs.
  4. Basically needed an asset compilation setup for development similar to what we’re accustomed to seeing in WordPress starter themes.

The compilation setup I was using at the time was bundled into the starter theme I was using so I ended up pretty much forking the compilation setup like this:

my-project
└─── wp-content
     └─── plugins
     │    └─── my-plugin
     │         │ package.json
     │         │ gulpfile.js
     │         │ webpack.config.js
     │         │ etc.
     │
     └─── themes
          └─── my-theme
               │ package.json
               │ gulpfile.js
               │ webpack.config.js
               │ etc.

So as a result I had two same same but different compilation setups. While this obviously worked, it was really inconvenient because I had to shut down and start up the gulp/webpack watch process depending on if I was working on the theme or the plugin.

Turning point #4

A few weeks ago (at the end of the jul 2019) I started finally working on the first (and still upcoming, you can order WPastronaut newsletter if you’d like to get notified when it’s released) course for this site that goes by the working title “Write better code with linters and autoformatters”.

I was still having my package.json/gulpfile.js/webpack.config.js inside my starter theme folder and run into some issues while trying to get some ESLint/Stylelint plugins to work with the VS Code Prettier extension. The problem seemed to be caused by the fact that all my Prettier/ESLint/Stylelint packages were inside my theme folder (like below) instead of the project root folder like this:

my-project
│ composer.json (php_codesniffer etc.)
│ phpcs.xml.dist
│
└─── wp-content
     └─── themes
          └─── my-theme
               │ assets/
               │ dist/
               │ package.json (gulp, webpack, prettier, eslint etc.)
               │ gulpfile.js
               │ webpack.config.js
               │ .editorconfig
               │ .eslintrc.js
               │ .stylelintrc.js
               │ etc.

At first I thought that the quickest workaround would be to refactor things like this:

my-project
│ composer.json (php_codesniffer etc.)
│ phpcs.xml.dist
│ package.json (prettier, eslint etc.)
│ .editorconfig
│ .eslintrc.js
│ .stylelintrc.js
│ etc.
│
└─── wp-content
     └─── themes
          └─── my-theme
               │ assets/
               │ dist/
               │ package.json (gulp, webpack etc.)
               │ gulpfile.js
               │ webpack.config.js
               │ etc.

This worked, but after seeing this my immediate thought was: what I just moved all the node_modules and asset compilation related stuff to the root of my WordPress project?

And then to move my files like this:

my-project
│ composer.json (php_codesniffer etc.)
│ phpcs.xml.dist
│ package.json (gulp, webpack, prettier, eslint etc.)
│ gulpfile.js
│ webpack.config.js
│ .editorconfig
│ .eslintrc.js
│ .stylelintrc.js
│ etc.
│
└─── wp-content
     └─── plugins
          └─── my-plugin
               │ assets/
               │ dist/
               │ uses the root compilation setup 😎
     └─── themes
          └─── my-theme
               │ assets/
               │ dist/
               │ uses the root compilation setup 😎

Suddenly a lot of things started to make sense. This is the way people uses package.json in most JavaScript based projects. After some additional thinking and talking with some of my colleagues I realized that there would be some issues that had to be solved to make this work really well. Some of them consisted:

  1. I would have to modify my current gulp/webpack setup quite a lot to be able to easily add custom compilation pipelines for the plugins and other themes (while running a multisite installation)
  2. It would be a bit harder (but not impossible) to open source starter themes this way because you just couldn’t open source the theme folder and call it a day

As I’m writing this blog post I haven’t had time to modify my gulp/webpack setup to see how complex it really is to have this kind of setup working, or if there are any additional downsides of this approach. My intuition says currently that this all makes a lot sense and that this all probably is going to be worth the effort. But as with many other development related problems, it’s hard to really know if there are some additional downsides of this approach before really making the switch.

What do you think? Do you spot any additional downsides of this approach? Let me know in the comments below.

P.S. if you’re interested in the end result of this, you can follow me (@WPastronaut) on Twitter or order WPastronaut newsletter here. This is not the highest item on my list but I’ll get there eventually 🙂