Skip to content

Instantly share code, notes, and snippets.

@aurooba
Last active June 26, 2020 22:30
Show Gist options
  • Save aurooba/dcea4e1c3baaba79cec0a5b2d2e31a2d to your computer and use it in GitHub Desktop.
Save aurooba/dcea4e1c3baaba79cec0a5b2d2e31a2d to your computer and use it in GitHub Desktop.
A basic Gulp.js file for WordPress Theme Development
/**
* Gulpfile.
*
* Workflow Supercharged
*
* Implements:
* 1. Live reloads browser with BrowserSync.
* 2. CSS: SCSS to CSS conversion, error catching, autoprefixing, sourcemaps, and CSS minification
* 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, JS, and PHP.
*
* @author Aurooba Ahmed <https://aurooba.com/>
*/
// a simple config file for destinations, sources, and final filenames
const config = require( './workflowsupercharged.config.js' );
//all them plugins
const { src, dest, series, parallel, watch } = require('gulp');
const pump = require('pump');
const plumber = require('gulp-plumber');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const autoprefixer = require('gulp-autoprefixer');
const newer = require('gulp-newer');
const imagemin = require('gulp-imagemin');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
const browserSync = require('browser-sync').create();
const replace = require('gulp-replace');
const prompt = require('gulp-prompt');
// data variables for user prompt
var themename = '';
var textdomain = '';
var url = '';
var author = '';
var authorurl = '';
var package = '';
var projecturl = '';
/**
* Task: Get the Terms
*
* Creates multiple user prompts used during Setup to make the necessary changes to the theme
*
*/
function get_the_terms() {
return src(['*.php', '**/*.php', 'scss/style.scss', '!build/**/*.php'])
.pipe(prompt.prompt([{
type: 'input',
name: 'theme',
message: 'Enter your theme name (e.g. WP Workflow Website):'
},
{
type: 'input',
name: 'textdomain',
message: 'Enter your theme\'s text domain (e.g. wp-workflow):'
},
{
type: 'input',
name: 'url',
message: 'Enter your theme\'s URL:'
},
{
type: 'input',
name: 'author',
message: 'Enter your name:'
},
{
type: 'input',
name: 'authorurl',
message: 'Enter your URL:'
},
{
type: 'input',
name: 'package',
message: 'Enter package name (e.g. workflow_supercharged, make sure spaces are underscores):'
},
{
type: 'input',
name: 'projecturl',
message: 'Enter your Local URL (without the protocol):'
},
], (result) => {
themename = result.theme;
textdomain = result.textdomain;
url = result.url;
author = result.author;
authorurl = result.authorurl;
package = result.package;
localurl = result.projecturl;
}))
};
/**
* Task: Replace the Terms in PHP
*
*/
function replace_terms_in_php() {
return src(['*.php', '**/*.php', '!build/**/*.php'])
.pipe(replace('function workflow_supercharged', 'function ' + package))
.pipe(replace('@package workflow_supercharged', '@package ' + package))
.pipe(replace('workflow-supercharged', textdomain))
.pipe(dest('.'))
}
/**
* Task: Replace the Terms in SCSS
*
*/
function replace_terms_in_scss() {
return src(['scss/style.scss'])
.pipe(replace('workflow-supercharged', textdomain))
.pipe(replace('Workflow Supercharged', themename))
.pipe(replace('https://wpworkflow.dev', url))
.pipe(replace('Aurooba Ahmed', author))
.pipe(replace('https://aurooba.com', authorurl))
.pipe(dest('scss'))
}
/**
* Task: Set Project URL in config file
*
*/
function set_projecturl() {
return src(['workflowsupercharged.config.js'])
.pipe(replace('workflowsupercharged.local', projecturl))
.pipe(dest('.'))
}
/**
* Task: Styles.
*
* Compiles SCSS, autoprefixes and minifies CSS output.
*
* This task does the following:
* 1. Get source scss file
* 2. Compile scss to CSS
* 3. Write sourcemaps for it
* 4. Autoprefix it and generate style.css and editor-style.css
* 7. Injects CSS and reloads browser with browserSync
*/
function styles(done) {
pump([
src('./scss/**/*.scss'),
sourcemaps.write('.'),
sass({outputStyle: config.outputStyle}).on('error', sass.logError),
autoprefixer(config.browserlist),
sourcemaps.write('.'),
sourcemaps.write('build'),
dest('.'),
dest('build'),
browserSync.stream(),
], function() {
console.log('SCSS changes compiled.');
});
// browserSync.reload();
done();
}
/**
* Task: PHP Files.
*
* Copies updated PHP files into the build folder, then reloads the browser with browserSync.
*
*/
function phpfiles(done){
pump([
src(['*.php', '**/*.php', '!build/**/*.php']),
plumber(),
dest('build'),
], function() {
console.log('PHP changes compiled.');
});
browserSync.reload();
done();
}
/**
* Task: Custom JS files.
*
* Uglifies custom JS files and copies into build folder, then reloads the browser with browserSync.
*
* This task does the following:
* 1. Gets the source folder for custom JS files
* 2. Concatenates all the files and generates theme.js
* 3. Renames the JS file with suffix .min.js
* 4. Uglifes/Minifies the JS file and generates vendors.min.js and pops it into build/
*/
function jscustom(done) {
pump([
src( config.jscustom, { base: config.jscustom } ),
plumber(),
// newer( config.jsvendors ),
concat( config.jscustomfile + '.js' ),
dest( config.jsoutput ),
rename({
basename: config.jscustomfile,
suffix: '.min'
}),
uglify(),
dest( 'build/js' )
], function() {
console.log('JS custom file changes compiled.');
});
browserSync.reload();
done();
}
/**
* Task: Vendor JS files.
*
* 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 and pops it into build/
*/
function jsvendors(done) {
pump([
src( config.jsvendors, { base: config.jsvendors } ),
newer( config.jsvendors ),
plumber(),
concat( config.jsvendorfile + '.js' ),
dest( config.jsvendoroutput ),
rename({
basename: config.jsvendorfile,
suffix: '.min'
}),
uglify(),
dest( 'build/js' )
], function() {
console.log('JS vendor file changes compiled.');
});
browserSync.reload();
done();
}
/**
* Task: Minify Images
*
* Minify images and copy them into the build folder in the right place.
*/
function images(done) {
pump([
src(config.imgsrc, {base: 'imgs/originals'}),
newer(config.imgdest),
imagemin({ optimizationLevel: 5, progressive: true, interlaced: true }),
dest(config.imgdest),
dest('build/imgs'),
], function() {
console.log('New images minified.');
});
browserSync.reload();
done();
}
/**
* Task: Update Screenshot
*
* Minify and update screenshot, then copy into build folder.
*/
function screenshot(done) {
pump([
src('screenshot.png'),
imagemin({ optimizationLevel: 5, progressive: true, interlaced: true }),
dest('.'),
dest('build')
], function() {
console.log('Screenshot updated and minified.');
});
done();
}
/**
* Task: Update Fonts
*
* Copy Fonts into build folder.
*/
function fontkit(done){
pump([
src('fontkit/*'),
plumber(),
dest('build/fontkit'),
], function() {
console.log('Fonts updated.');
});
browserSync.reload();
done();
}
/**
* Task: Watch for all changes
*
*/
function watchlist() {
console.log('Watching your files for changes now..');
browserSync.init({
open: 'external',
host: config.projectURL,
proxy: config.projectURL,
browserAutoOpen: config.browserAutoOpen,
injectChanges: config.injectChanges,
});
// Watch files
watch('scss/*.scss', parallel(styles));
watch('scss/**/*.scss', parallel(styles));
watch('imgs/originals/**', parallel(images));
watch(['*.php', '**/*.php', '!build/**/*.php'], parallel(phpfiles));
watch(config.jscustom, parallel(jscustom));
watch(config.jsvendors, parallel(jsvendors));
watch('screenshot.png', parallel(screenshot));
watch('fontkit/*', parallel(fontkit));
}
exports.setup = series(get_the_terms, replace_terms_in_php, replace_terms_in_scss, set_projecturl);
exports.build = parallel(styles, images, phpfiles, jscustom, jsvendors, screenshot, fontkit);
exports.watch = watchlist;
{
"name": "workflow-supercharged",
"version": "1.0.0",
"description": "A streamlined workflow for WordPress theme developers",
"homepage": "https://wpworkflow.dev",
"author": "Aurooba Ahmed (https://aurooba.com/)",
"license": "GPL",
"scripts": {
"start": "npm install && gulp setup && gulp watch"
},
"devDependencies": {
"browser-sync": "^2.26.7",
"gulp": "^4.0.0",
"gulp-autoprefixer": "*",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "*",
"gulp-imagemin": "*",
"gulp-newer": "*",
"gulp-plumber": "*",
"gulp-prompt": "^1.2.0",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.0.0",
"gulp-sass": "*",
"gulp-sourcemaps": "^2.6.5",
"gulp-uglify": "^3.0.2",
"pump": "^3.0.0",
"tiny-lr": "*"
}
}
/**
* Workflow Supercharged Configuration File
*
*
* @package workflow_supercharged
*/
module.exports = {
// Project options.
projectURL: 'workflowsupercharged.local',
browserAutoOpen: true,
injectChanges: true,
// Style options.
outputStyle: 'compressed',
// Image options.
imgsrc: 'imgs/originals/*',
imgdest: 'imgs',
// JS Vendor options.
jsvendors: './js/vendors/**/*.js',
jsvendoroutput: 'js',
jsvendorfile: 'vendors', // Compiled JS custom file name: vendors.js
// JS Custom options.
jscustom: './js/custom/**/*.js', // JS custom scripts folder.
jsoutput: 'js', // Path to place the compiled JS custom scripts file.
jscustomfile: 'theme', // Compiled JS custom file name: theme.js
// Browsers you care about for autoprefixing. Browserlist https://github.com/ai/browserslist. The list is per WordPress requirements.
browserslist: [
'last 2 version',
'> 1%',
'ie >= 11',
'last 1 Android versions',
'last 1 ChromeAndroid versions',
'last 2 Chrome versions',
'last 2 Firefox versions',
'last 2 Safari versions',
'last 2 iOS versions',
'last 2 Edge versions',
'last 2 Opera versions'
]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment