Using Gulp in WordPress

Gulp for WordPress themes and Plugins can boost your development speed. One word AUTOMATION in basic terminology that defines gulp. Web developers often find themselves doing repetition in small and tedious work on daily basis which can be simplified by implementing gulp and automation.

Without gulp assumption -> repetitive tasks = time consuming = loss in productivity.

With gulp assumption -> automated repetitive tasks = focus on more important tasks = More productivity

Quick Edit March 18th, 2017

Gulp does not need to be installed globally. Only Gulp CLI needs to be installed globally.
This is because, installing gulp globally effectively has no use, instead the local version of gulp is used in projects.

-Corrected by @digambar




So, What is Gulp Exactly?

Gulp is a javascript task runner that lets you automate tasks defined using code over configuration. There is another famous task runner that exists known as Grunt. Comparing the two gulp is more easier to implement.

Though you will need to know basics on javascript and basic knowledge on configuration logics.

Few tasks that Gulp handles such as..

  1. Live reloads browser with BrowserSync
  2. CSS: Sass to CSS conversion, error catching, Autoprefixing, Sourcemaps, CSS minification, and Merging Media Queries
  3. JS: Concatenates & uglifies Vendor and Custom JS files
  4. Images: Minifies PNG, JPEG, GIF and SVG images
  5. Watches files for changes in CSS or JS
  6. Watches files for changes in PHP
  7. Corrects the line endings
  8. InjectCSS instead of browser page reload
  9. Generates .pot file for i18n and l10n

Note: At the time of this post BrowserSync does not work as expected and kinda slow. So not recommending.

Getting Started with Gulp

Please note that you do not need to know node to implement gulp. You will only need node installed which you can look up in nodejs site. Installation might vary according to operating system but it is not difficult to install.

As gulp uses node in order to execute tasks so the only explanation we will be looking into is how gulp works and how we can implement in our WordPress project.

Installing Node and NPM package manager

Code gulp

Currently i am using a windows machine however, process is same for all operating system. So, before we start you will need to install Node js on your machine (https://nodejs.org/en/download/) or install it using a command line.

Once, installed open up terminal or command and type:

node -v
npm -v

These above should be typed separately. If node is installed then their version numbers will be shown like in above screenshot. If either fails then check your command or verify that you installed your node js correctly.

Installing Gulp

In order to use gulp in your projects, you will need to install it globally like following.

sudo npm install gulp -g

For linux, mac with sudo commands do above and for windows users – Open up command prompt and type the same but without sudo.

Code gulp

The -g parameter in command defines that the corresponding package to be installed globally into system. Now, to verify that gulp is installed you check by following command.

gulp -v

Diving into WordPress

We will implement gulp in our plugins for this project, You can do it for themes as well. Same process but only different directory 🙂

Clone Gulp Boilerplate from github by doing:

git clone https://github.com/techies23/WP-Plugin-Gulp-Boilerplate

or you can create a new folder in your plugins directly and name it anything you want. Download files from github and keep it into your plugin folder.

You will find a package.json and gulpfile.js file in the plugin directory. These files are crucial in order to implement gulp in a project. Package.json file will hold dependencies to your project whereas, gulfile.js is configuration file for using gulp.

Now that you have created or copied either way we are ready to implement gulp in our project.

Understanding package.json file

Create a gulpfile.js and keep it empty for now. Run npm init on your command/ terminal.

Package.json file is created and used by npm to manage dependencies/package for your project. In order to create this file you can run npm init on your command/ terminal. Running npm init will ask you some details to be filled up. After installing gulp create a package.json file via npm init. After you have filled in details run npm install gulp –save-dev.

This will install gulp into your project and automatically save it in your package.json file.

  {
    "name": "wp-plugin-gulp",
    "version": "1.0.0",
    "description": "Basic Boilerplate Template for WordPress plugin Gulp Usage",
    "main": "gulpfile.js",
    "repository": {
      "type": "git",
      "url": "https://github.com/techies23/WP-Plugin-Gulp-Boilerplate.git"
    },
    "keywords": [
    "boilerplate",
    "gulp",
    "wp",
    "plugin"
    ],
    "devDependencies": {
      "gulp": "^3.9.1",
      "gulp-autoprefixer": "^3.1.0",
      "gulp-concat": "^2.6.1",
      "gulp-jshint": "^2.0.4",
      "gulp-notify": "^2.2.0",
      "gulp-plumber": "^1.1.0",
      "gulp-rename": "^1.2.2",
      "gulp-sass": "^3.1.0",
      "gulp-sourcemaps": "^2.4.0",
      "gulp-uglify": "^2.0.0",
      "gulp-uglifycss": "^1.0.6",
      "jshint": "^2.9.4",
      "jshint-stylish": "^2.2.1"
    },
    "author": "Deepen Bajracharya",
    "license": "GPL-2.0+"
  }

After you have installed open your package.json file and copy above devDependencies to your package.json file or simply copy whole above code to your package.json file.

I will not be going through each and every dependencies on what they do. I suggest you google them for their purpose.

Now after creating both gulfile.js and package.json you will need to fetch those dependencies on your project which you can do by running following code.

sudo npm install or npm install

This will create a folder node_modules which can be seen when installing gulp into your project as well. After the fetching is completed our dependencies are ready and waiting to be used by gulpfile in our project.

Implementing Gulp

Now the final part where all magic begins. Gulp file needs to be in root of the project that we are implementing gulp on. In our case i.e wp-content > plugins > our-project.

Gulp is easy since its code over configuration.

Simple Gulp API

Gulp contains only 4 api’s which are easier to understand and implement. So, you won’t need to figure out how complex an API works. Cool eh ?

APIPurpose
gulp.taskDefine a task
gulp.srcRead files in
gulp.destWrite files out
gulp.watchWatch files for changes

Let us take a look at gulfile.js.

A. Configuration

The below code are just basic variables to be used in later process. They define the path of files to be compressed, minified and watch when modified or changed. Read comments to know exactly what they do.

/**
* Configuration.
*
* Project Configuration for gulp tasks.
*
* Edit the variables as per your project requirements.
*/

var project             = 'wp-plugin-gulp'; // Name

var styleSRC            = './files/assets/css/**/style.scss'; // Path to main .scss file
var styleDestination    = './files/css/'; // Path to place the compiled CSS file

var jsVendorSRC         = './files/assets/vendors/*.js'; // Path to JS vendors folder
var jsVendorDestination = './files/js/'; // Path to place the compiled JS vendors file
var jsVendorFile        = 'vendors'; // Compiled JS vendors file name

var jsCustomSRC         = './files/assets/js/*.js'; // Path to JS custom scripts folder
var jsCustomDestination = './files/js/'; // Path to place the compiled JS custom scripts file
var jsCustomFile        = 'custom'; // Compiled JS custom file name
// Default set to custom i.e. custom.js

var styleWatchFiles     = './files/assets/css/**/*.scss'; // Path to all *.scss files inside css folder and inside them
var vendorJSWatchFiles  = './files/assets/js/vendors/*.js'; // Path to all vendors JS files
var customJSWatchFiles  = './files/assets/js/*.js'; // Path to all custom JS files

B. Loading Dependencies

Below code loads necessary dependecies for implementing/ automating some tasks. Such as script concatination, code prefixing, minifying css and js, comiling SASS to CSS and many more. You will need to require dependencies here in order to use them in your automation task.

/**
* Load Dependencies.
*/
var gulp = require('gulp'); // Gulp of-course

// CSS related plugins.
var sass = require('gulp-sass'); // Gulp pluign for Sass compilation
var autoprefixer = require('gulp-autoprefixer'); // Autoprefixing magic
var minifycss = require('gulp-uglifycss'); // Minifies CSS files

// JS related plugins.
var concat = require('gulp-concat'); // Concatenates JS files
var uglify = require('gulp-uglify'); // Minifies JS files
var plumber = require('gulp-plumber');
var jshint = require('gulp-jshint');

// Utility related plugins.
var rename = require('gulp-rename'); // Renames files E.g. style.css -> style.min.css
var sourcemaps = require('gulp-sourcemaps'); // Maps code in a compressed file (E.g. style.css) back to it’s original position in a source file (E.g. structure.scss, which was later combined with other css files to generate style.css)
var notify = require('gulp-notify'); // Sends message notification to you

C. Automating Styles

Next code is to automate stylesheet tasks such as comiling SCSS to CSS and minifying them into a single file in a specified directory which is defined in configuration part.

/**
 * Task: styles
 *
 * Compiles Sass, Autoprefixes it and Minifies CSS.
 *
 * This task does the following:
 *    1. Gets the source scss file
 *    2. Compiles Sass to CSS
 *    3. Writes Sourcemaps for it
 *    4. Autoprefixes it and generates style.css
 *    5. Renames the CSS file with suffix .min.css
 *    6. Minifies the CSS file and generates style.min.css
 */
 gulp.task('styles', function(){
  return gulp.src(styleSRC)
  .pipe(plumber({errorHandler: notify.onError("Error: <%= error.message %>")}) )
  .pipe(sourcemaps.init())
  .pipe(sass({
    errLogToConsole: true,
    outputStyle: 'compact',
    //outputStyle: 'compressed',
    // outputStyle: 'nested',
    // outputStyle: 'expanded',
    precision: 10
  }))
  .pipe( sourcemaps.write( { includeContent: false } ) )
  .pipe( sourcemaps.init( { loadMaps: true } ) )
  .pipe( autoprefixer(
    'last 2 version',
    '> 1%',
    'safari 5',
    'ie 8',
    'ie 9',
    'opera 12.1',
    'ios 6',
    'android 4' ) )
  .pipe( sourcemaps.write ( styleDestination ) )
  .pipe( gulp.dest( styleDestination ) )
  .pipe( minifycss ({
    "maxLineLen": 80,
    "uglyComments": true
  }))
  .pipe( rename( { suffix: '.min' } ) )
  .pipe( gulp.dest( styleDestination ) )
  .pipe( notify( { message: 'TASK: "styles" Completed! 💯', onLast: true } ) );
});

D. Automating JS

Another task is to concatinate, minify js files to defined location in configuration settings.

/**
 * Task: vendorJS
 *
 * Concatenate and uglify vendor JS scripts.
 *
 * This task does the following:
 *    1. Gets the source folder for JS vendor files
 *    2. Concatenates all the files and generates vendors.js
 *    3. Renames the JS file with suffix .min.js
 *    4. Uglifes/Minifies the JS file and generates vendors.min.js
 */
 gulp.task( 'vendorsJs', function() {
  gulp.src( jsVendorSRC )
  .pipe( plumber({errorHandler: notify.onError("Error: <%= error.message %>")}) )
  .pipe( jshint() )
  .pipe( jshint.reporter('jshint-stylish') )
  .pipe( concat( jsVendorFile + '.js' ) )
  .pipe( gulp.dest( jsVendorDestination ) )
  .pipe( rename( {
    basename: jsVendorFile,
    suffix: '.min'
  }))
  .pipe( uglify() )
  .pipe( gulp.dest( jsVendorDestination ) )
  .pipe( notify( { message: 'TASK: "vendorsJs" Completed!', onLast: true } ) );
});

/**
 * Task: customJS
 *
 * Concatenate and uglify custom JS scripts.
 *
 * This task does the following:
 *    1. Gets the source folder for JS custom files
 *    2. Concatenates all the files and generates custom.js
 *    3. Renames the JS file with suffix .min.js
 *    4. Uglifes/Minifies the JS file and generates custom.min.js
 */
 gulp.task( 'customJS', function() {
  gulp.src( jsCustomSRC )
  .pipe( plumber({errorHandler: notify.onError("Error: <%= error.message %>")}) )
  .pipe( jshint() )
  .pipe( jshint.reporter('jshint-stylish') )
  .pipe( concat( jsCustomFile + '.js' ) )
  .pipe( gulp.dest( jsCustomDestination ) )
  .pipe( rename( {
    basename: jsCustomFile,
    suffix: '.min'
  }))
  .pipe( uglify() )
  .pipe( gulp.dest( jsCustomDestination ) )
  .pipe( notify( { message: 'TASK: "customJs" Completed!', onLast: true } ) );
});

E. Watch

Finally the default task, which will trigger all the other tasks in our file. Thats all there is to it to implement gulp.

/**
  * Watch Tasks.
  *
  * Watches for file changes and runs specific tasks.
  */

  gulp.task( 'default', [ 'styles', 'vendorsJs', 'customJS' ], function () {
    gulp.watch( './files/assets/css/**/*.scss', [ 'styles' ] );
    gulp.watch( './files/assets/js/vendors/*.js', [ 'vendorsJs' ] );
    gulp.watch( './files/assets/js/*.js', [ 'customJS' ] );
  });

Now, run gulp in your command or terminal. This will automate task for you. Your scripts will be minified, prefixed and convered from SASS to CSS; saved in defined directories.

There is more to do with gulp. You have already learned the basics and implemented it in your project and you already know that this is not so hard. So, why stop here ?

You can find this implementation or boilerplate for gulp in WP plugin in github.

ABOUT THE AUTHOR

In a world without walls and fences, who needs windows and gates ? No gates, no windows bt apache inside! #dev Love for #Unix #Linux #Apple. Interests in coding, music, creative design, Linux and Apple products.

You may also like...

2 Responses

  1. Digamber says:

    Great Article,
    but will recommend a quick edit,
    Gulp does not need to be installed globally.
    Only Gulp CLI needs to be installed globally.
    This is because, installing gulp globally effectively has no use, instead the local version of gulp is used in projects.

    see Local vs Global Gulp

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.