Jake McMurchie saxophonist and Wordpress developer

Jake McMurchie

My development environment

Using Node NPM and Git for WordPress theme development

SASS, minification, version control, deployment containers, build pipelines?

I’ve managed with good, old-fashioned Coda and Codekit for many years – Codekit in particular is a fantastic tool and every time I looked into NPM, other package managers, and associated tools, I realised that Codekit took care of them for me. Plus the portability that NPM etc. provide (i.e., the ability to set up a dev environment that could easily be picked up by someone else) never seemed to apply because I worked either alone or with someone who wasn’t likely to embrace the technical challenges a command line-based set-up would entail.

But it’s now standard practice to use SASS or LESS, some kind of package manager, and source control – not to mention some kind of deployment process – for web development. So here’s my personal route based on my recent conversion. It’s rudimentary, and I’ll expand on it as I learn, but it works and it’s been tested by doing it.

Assumptions

Create your site

Start by creating a folder for your site e.g.:

~/Sites/mysite/

In there I create a folder /web for the site that will be served.

Now create your virtual host to point at the /web folder e.g.:

https://mysite.test

… and install WordPress in there.

Now open Terminal and set up npm and your package.json to manage your tools in the theme:

cd ~/Sites/mysite/wp-content/themes
mkdir mytheme
cd mytheme
npm init

The last of these commands takes up through the set up of the package.json, our code framework for running the project.

I set my folder structure up like so:

/css/
/images/
/inc/
/scripts/
/src/
 -js/
 -scss/

Install node packages

Now install the node packages, using the --save-dev flag because we only want to use these packages while we’re developing:

npm install --save-dev node-sass for compiling SCSS into CSS

npm install --save-dev autoprefixer for adding the proprietory browser prefixes for CSS

npm install --save-dev postcss-cli so we can run autoprefixer once the SCSS has been compiled

npm install --save-dev uglify-js for javascript compiling and minifying

npm install --save-dev onchange so we can watch for changes and run the modules above

npm install --save-dev browser-sync so the browser refreshes when we make those changes

npm install --save-dev --save-exact parallelshell@3.0.1 so we can run several simultaneous watch scripts to make our changes and refresh the browser. Note: I used –save-exact and specified version 3.0.1 because of a problem with node version > 11 and parallelshell version > 3.0.1…

The commands above will automatically update package.json, so now we can add our scripts to package.json:

"scripts": {
    "compilesass": "node-sass --source-map true --source-map-embed true --source-map-contents true --source-map-root true --output-style nested --indent-type spaces --indent-width 4 -o css src/scss",
    "autoprefixer": "postcss -u autoprefixer -r css/*.css",
    "build:css": "npm run compilesass && npm run autoprefixer",
    "watch:css": "onchange 'src/scss/**/*.scss' -- npm run build:css",
    "minifyjs": "uglifyjs src/js/app.js --compress --output scripts/app.js",
    "build:js": "npm run minifyjs",
    "watch:js": "onchange 'src/js/**/*.js' -- npm run build:js",
    "serve": "browser-sync start --files '**/*' --ignore 'src/**/*' --proxy http://mysite.test",
    "watch": "parallelshell 'npm run serve' 'npm run watch:css' 'npm run watch:js'"
  }

Note the --ignore 'src/**/* in the serve script – this means the browser only refreshes when the files you intend to serve are updated, not the source files. If it updates when the source files are updated, the browser refreshes before the js/css files have finished compiling.

Your package.json should now look like this:

{
  "name": "MyTheme",
  "version": "1.0.0",
  "description": "",
  "main": "",
  "scripts": {
    "compilesass": "node-sass --source-map true --source-map-embed true --source-map-contents true --source-map-root true --output-style nested --indent-type spaces --indent-width 4 -o css src/scss",
    "autoprefixer": "postcss -u autoprefixer -r css/*.css",
    "build:css": "npm run compilesass && npm run autoprefixer",
    "watch:css": "onchange 'src/scss/**/*.scss' -- npm run build:css",
    "minifyjs": "uglifyjs src/js/app.js --compress --output scripts/app.js",
    "build:js": "npm run minifyjs",
    "watch:js": "onchange 'src/js/**/*.js' -- npm run build:js",
    "serve": "browser-sync start --files '**/*' --ignore 'src/**/*' --proxy http://offlinesite.test",
    "watch": "parallelshell 'npm run serve' 'npm run watch:css' 'npm run watch:js'"
  },
  "repository": {
    "type": "git",
    "url": "mytheme"
  },
  "author": "Jake",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "autoprefixer": "^9.8.0",
    "browser-sync": "^2.26.7",
    "node-sass": "^4.14.1",
    "onchange": "^7.0.2",
    "parallelshell": "3.0.1",
    "postcss-cli": "^7.1.1",
    "uglify-js": "^3.9.3"
  }
}

Set up source control

Back to terminal:

git init

Now create the file .gitignore and add the files you don’t want added to the repository:

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# npm generated files #
#######################
node_modules
build
npm-debug.log
.env

Getting it working

This is the easy bit:

npm run watch

This will open a new browser window which will update when you make any changes to your code.