Skip to content

Instantly share code, notes, and snippets.

@mae829
Last active March 17, 2021 18:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mae829/9e5701ccc64a0d76c5a1e7af53079033 to your computer and use it in GitHub Desktop.
Save mae829/9e5701ccc64a0d76c5a1e7af53079033 to your computer and use it in GitHub Desktop.
Gulp project setup
/**
* WPGulp Configuration File
*
* 1. Edit the variables as per project requirements.
* 2. Everything else is in the gulpfile to keep it consistent across our projects.
*/
// Define the default project configuration.
let projectConfig = {
// Local project URL of your already running WordPress site. Could be something like wpgulp.local or localhost:3000 depending upon your local WordPress setup.
serverConfig: {
proxy: 'testing.loc'
}
};
/**
* Check for local project config and overwrite it
*
* Create a file that exports your local configuration as an object to use a custom projectUrl and/or browsers list (if you really must).
*/
import fs from 'fs';
if ( fs.existsSync( './gulp.config.local.js' ) ) {
const localConfig = require( './gulp.config.local.js' );
projectConfig = { ...projectConfig, ...localConfig };
}
module.exports = projectConfig;
/**
* Gulpfile.
*
* Gulp with WordPress.
*
* Implements:
* 1. Live reloads browser with BrowserSync.
* 2. CSS: SCSS to CSS conversion, error catching, Autoprefixing, Sourcemaps,
* CSS minification, and Merge Media Queries.
* 3. JS: Concatenates & uglifies Vendor and Custom JS files.
* 4. Watches files for changes in CSS or JS.
* 5. Watches files for changes in PHP.
* 6. InjectCSS instead of browser page reload.
*
* Modded from https://github.com/ahmadawais/WPGulp
*
* Dependencies:
* - gulp.config.js
* - .babelrc
* - .sass-lint.yml
* - .eslintignore
* - .eslintrc.json
* - .browserlistrc (run `npx browserslist-ga` to get site's statistics)
*/
/**
* Load WPGulp Configuration.
*/
import config from './gulp.config.js';
/**
* Load Plugins.
*
* Load gulp plugins and passing them semantic names.
*/
import { dest, parallel, src, series, watch } from 'gulp';
// CSS related plugins.
import autoprefixer from 'gulp-autoprefixer';
import cleanCSS from 'gulp-clean-css';
import sass from 'gulp-sass';
import sassLint from 'gulp-sass-lint';
// JS related plugins.
import babel from 'gulp-babel';
import eslint from 'gulp-eslint';
import include from 'gulp-include';
import uglify from 'gulp-uglify';
// Utility related plugins.
import browserSync from 'browser-sync';
import del from 'del';
import notify from 'gulp-notify';
import plumber from 'gulp-plumber';
import rename from 'gulp-rename';
const server = browserSync.create();
/**
* Custom Error Handler.
*
* @param Mixed error
*/
const errorHandler = error => {
notify.onError( {
title: 'Gulp error in ' + error.plugin,
message: error.toString(),
sound: false
} )( error );
};
/**
* Task: `browser-sync`.
*
* Live Reloads, CSS injections, Localhost tunneling.
* @link http://www.browsersync.io/docs/options/
*
* @param {Mixed} done Done.
*/
const browsersync = done => {
const baseServerConfig = {
open: false,
watchEvents: [ 'change', 'add', 'unlink', 'addDir', 'unlinkDir' ]
};
const serverConfig = { ...baseServerConfig, ...config.serverConfig };
server.init( serverConfig );
done();
};
// Helper function to allow browser reload with Gulp 4.
const reload = done => {
server.reload();
done();
};
/**
* Task: `scssLinter`.
* This task does the following:
* 1. Gets all our scss files
* 2. Lints theme files to keep code up to standards and consistent
*/
export const scssLinter = () => {
return src( 'src/scss/**/*.scss' )
.pipe( plumber( errorHandler ) )
.pipe( sassLint() )
.pipe( sassLint.format() )
.pipe( sassLint.failOnError() );
};
scssLinter.description = 'Lint through all our SCSS files so our code is consistent across files.';
/**
* Task: `css`.
*
* This task does the following:
* 1. Gets the source scss file
* 2. Compiles SCSS to CSS
* 3. Writes Sourcemaps for it
* 4. Autoprefixes it
* 5. Renames the CSS file with suffix .min.css
* 6. Minifies the CSS file and generates *.min.css
* 7. Injects CSS or reloads the browser via server
*
* - Creates both a fully expanded and minified version of front-end files.
* - Keeping both files helps see the generated changes in version control.
*/
export const css = ( done ) => {
// Clean up old files.
del( './assets/css/*' );
src( 'src/scss/wp-*.scss', { sourcemaps: true } )
.pipe( plumber( errorHandler ) )
.pipe( sass( { outputStyle: 'compressed' } ).on( 'error', sass.logError ) )
.pipe( rename( { suffix: '.min' } ) )
.pipe( dest( './assets/css', { sourcemaps: '.' } ) );
src( [
'src/scss/*.scss',
'!src/scss/wp-*.scss'
], { sourcemaps: true } )
.pipe( plumber( errorHandler ) )
.pipe( sass( { outputStyle: 'expanded' } ).on( 'error', sass.logError ) )
.pipe( dest( './assets/css' ) )
.pipe( autoprefixer( {
cascade: false
} ) )
.pipe( cleanCSS( {
level: {
2: {
all: false,
mergeIntoShorthands: true,
mergeMedia: true
}
}
} ) )
.pipe( rename( { suffix: '.min' } ) )
.pipe( dest( './assets/css', { sourcemaps: '.' } ) )
.pipe( server.stream( {
match: '**/*.css' // Sourcemap is in stream so match for actual CSS files
} ) );
done();
};
css.description = 'Compiles SCSS, Autoprefixes it and Minifies CSS.';
/**
* Task: `jsLint`.
* This task does the following:
* 1. Gets all our theme files
* 2. Lints theme files to keep code up to standards and consistent
*/
export const jsLint = () => {
return src( [
'./src/js/**/*.js',
'!src/js/vendor/**'
] )
.pipe( eslint() )
.pipe( eslint.format() );
};
jsLint.description = 'JS linter task to keep our code consistent.';
/**
* Task: `js`.
*
* This task does the following:
* 1. Gets the source folder for JS files
* 2. Concatenates all the files and generates *.js
* 3. Renames the JS file with suffix .min.js
* 4. Uglifes/Minifies the JS file and generates *.min.js
*/
export const js = () => {
// Clean up old files.
del( './assets/js/*' );
return src( 'src/js/*.js', {
sourcemaps: true
} )
.pipe( plumber( errorHandler ) )
.pipe( include( {
includePaths: [
__dirname + '/src/js',
__dirname + '/node_modules'
]
} ) )
.pipe( babel() ) // config is in .babelrc file
.pipe( uglify() )
.pipe( rename( { suffix: '.min' } ) )
.pipe( dest( './assets/js', { sourcemaps: '.' } ) )
.pipe( server.reload( {
match: '**/*.js', // Sourcemap is in stream so match for actual JS files
stream: true
} ) );
};
js.description = 'Run all JS compression and sourcemap work.';
export const styles = series( scssLinter, css );
export const scripts = series( jsLint, js );
export const build = parallel( styles, scripts );
/**
* Watch Tasks.
*/
export const dev = series( build, browsersync, () => {
watch( './**/*.php', reload );
watch( './src/scss/**/*.scss', styles );
watch( './src/js/**/*.js', scripts );
} );
dev.description = 'Watches for file changes and runs specific tasks.';
export default dev;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment