Gulp setup for WordPress Theme Development
As a follow up to my previous post where I show you a Gulp setup for static sites development, today, I want to share a Gulp setup for working with WordPress. The goal is to integrate Gulp into your existing WordPress development environment and take advantage of all the file processing goodness Gulp has to offer.
This file was heavily inspired by Morten Rand-Hendriksen’s setup from one of his courses on Lynda.com. You can check out his website at https://mor10.com to learn more about Monten.
I am assuming you have downloaded and ran Gulp locally on your machine. But if not, please check out Gulps ‘Quick Start’ page to get it installed and ready to go.
Also, please make sure to copy the package.json
file from this repo and download the dependencies by running npm install
This Gulp file will be just like the file I shared on my last post with just a few adjustments. So if you are new to Gulp I recommend you check out that post as I provide a bit more detail on each task which may be useful for the new Gulp user. On this post I will be using the same file and just point out the adjustments made for WordPress and why it changed for this setup.
Ok, so lets start.
The Directory Structure
This Gulp file should live inside a directory with a name of your choosing, mine is named gulp-dev
, and this directory should be placed in your WordPress themes directory along with your main theme, which in my case it is called hsnyc
.
wp-content
- themes
-- gulp-dev
--- gulpfile.js
--- package.json
-- hsnyc
--- scss
--- js
--- images
---- RAW
--- languages
--- ...
- plugins
...
The Imports
At the top of the file we will get the necessary functions from Gulp.
const { src, dest, watch, series, parallel } = require('gulp');
Then, we will import the following modules.
const sourcemaps = require('gulp-sourcemaps');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const image = require('gulp-image');
const jshint = require('gulp-jshint');
const stylish = require('jshint-stylish');
const browserSync = require('browser-sync').create();
var replace = require('gulp-replace');
The Variables
Next, I will be setting up some variables that we will need in the construction of each task.
Theme variable
We will use this variable to store our theme name. Make sure you assign it the name of the theme you will be working on.
//your theme name
var themename = 'hsnyc';
File paths variables
These variables will hold the path to the files inside your theme’s directory.
var root = '../' + themename + '/',
scss = root + 'sass/',
js = root + 'js/',
img = root + 'images/',
languages = root + 'languages/';
The Tasks
Please note that these can be named any way you like. We will have one less task compared to the static sites files. We will not be using the cache bust so there will be 4 tasks instead of 5: scssTask
, jsTask
, imgTask
, and the watchTask
.
The SASS Task
The main thing I am accomplishing here is to compile the style.scss
file found in the theme’s scss
directory to a style.css
file that will be placed in the theme directory.
function scssTask(){
return src(scss + 'style.scss')
.pipe(sourcemaps.init()) // initialize sourcemaps first
.pipe(sass({
outputStyle: 'expanded',
indentType: 'tab',
indentWidth: '1'
}).on('error', sass.logError)) // compile SCSS to CSS
.pipe(postcss(autoprefixer()))
.pipe(sourcemaps.write(scss + 'maps'))
.pipe(dest(root));
}
The notable difference from my static sites Gulp file is that I am not checking an env
variable to see if on production or development. That was done so postcss
can auto prefix and minify the css files if in production. In this task, I will just leave it as is. I am also passing in some options for sass
(outputStyle, indentType, indentWidth) but those are optional and you can just leave them out if you choose.
The Js Task
In the Js task I am only running jshint on any javascript files I write which I place in the js directory. I place any third party libraries in a ‘lib’ or ‘vendor’ directory under the js directory and I do not lint those.
function jsTask(){
return src([js + '*.js'])
.pipe(jshint()) //to ignore some files or directories, create a .jshintignore file and add the files/dirs you want to ignore - https://jshint.com/docs/cli/
.pipe(jshint.reporter(stylish))
}
I am using the stylish jshint reporter, by Sindre Sorhus, to make the output look nicer.
The Image Task
In this task I am optimizing images I place in a directory named RAW
, which is inside the images
directory, and outputting the optimized images outside of RAW
.
function imgTask(){
return src(img + 'RAW/**/*.{jpg,JPG,png}')
.pipe(newer(img))
.pipe(image())
.pipe(dest(img));
}
In this file I am using gulp-image
instead of gulp-imagemin
. There is no right or wrong, it’s just a matter of preference. gulp-image
is a bit more simple in my opinion. One thing I didn’t add to my static file is gulp-newer
which will only grab the source files that are newer than the destination files.
The Watch Task
The watch task will, you guessed it, watch the files for any changes and if any changes are made, it will execute a task.
function watchTask(){
//start BrowserSync server
server();
watch(scss + '*.scss', scssTask);
watch(js + '**/*.js', jsTask);
watch(img + 'RAW/**/*.{jpg,JPG,png}', imgTask);
watch(root + '**/*').on('change', browserSync.reload);
};
The first thing is to start the BrowserSync server using server()
(see server function next) Then, using Gulp watch, we will monitor our html, scss, js, and image files and if any changes occur we run the corresponding task. One difference here is that I am using one watch function to reload instead of reloading on each task, like I do on my static Gulp file. I will consolidate the differences in these files at some point, but for now you can do it either way. I am sure there is performance gain by doing it one way over the other.. But it’s just too negligible to worry about, especially on a local setup.
And that was the final task on the file.
The following is the BrowserSync built-in server configurations.
// https://www.browsersync.io/docs/options#option-server
function server() {
browserSync.init({
proxy: 'hsnycwp.local', //alias
port: 8080, //<-- changed default port (default:3000). Make sure to use proxy url + port for reload to work i.e http://hsnycwp.local:8080
open: false //<-- set false to prevent opening browser
});
}
Here are the options we specify:
proxy
: If you have a setup that uses a local domain alias this is where you would specify it. This is the alias I am using with Docker.port
: Is the port number I want to use. The default is 3000 if it’s not specified.open
: Allows you to choose if the browser should open automatically when the server starts. I want to open it manually so I have set it tofalse
.
Default Task
And finally, we will export our default task which will be the watchTask
. This task will start the monitoring of the files.
exports.default = watchTask;
And that’s all there is to it. With this file you will be able to add a Gulp workflow, within your WordPress dev setup, that allows you to compile sass files, lint Js files, compress and optimize images, and refresh the browser upon any edits. Also, remember to copy the package.json
file if you decide to start with this Gulp file.
I hope this post helps you make your WordPress theme development easier by automating some of the most repetitive dev tasks.
If you have any feedback, suggestions, or questions please do leave them on the comment section below. I do read and try to respond to every comment.
Thanks for reading!