├── .jshintrc ├── README.md ├── gulp ├── config.js ├── dependencies ├── tasks │ ├── build.js │ ├── clean.js │ ├── default.js │ ├── dist-copy.js │ ├── dist-images.js │ ├── dist-styles.js │ ├── dist-wipe.js │ ├── dist.js │ ├── help.js │ ├── images-optimize.js │ ├── images.js │ ├── scripts-lint.js │ ├── scripts-uglify.js │ ├── scripts.js │ ├── styles-lint.js │ ├── styles-postcss.js │ ├── styles-sass.js │ ├── styles.js │ └── watch.js └── util │ ├── handleErrors.js │ └── mergeRecursive.js └── gulpfile.js /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "eqnull": true, 6 | "es3": true, 7 | "expr": true, 8 | "immed": true, 9 | "noarg": true, 10 | "onevar": true, 11 | "quotmark": "single", 12 | "trailing": true, 13 | "undef": true, 14 | "unused": true, 15 | 16 | "browser": true, 17 | 18 | "globals": { 19 | "_": false, 20 | "Backbone": false, 21 | "jQuery": false, 22 | "JSON": false, 23 | "wp": false 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Basic modular gulp setup for use in WordPress theme development. 2 | 3 | This is the basic modular gulp starter setup that is used for [wpdevelopersclub.com](https://wpdevelopersclub.com) courses. 4 | 5 | - __Contributors:__ [Alain Schlesser](http://www.alainschlesser.com) 6 | - __License:__ [GPL-2.0+](http://www.gnu.org/licenses/gpl-2.0.html) 7 | 8 | ## Features 9 | 10 | ### General 11 | 12 | * Modular structure that is easy to extend, with each task in a separate file. 13 | * Single configuration file that allows a quick adaptation to the folder structure of a project. 14 | * Error handling that pops up notifications and keeps the watch task running on error. 15 | 16 | ### Styles 17 | 18 | * Linting through [Stylelint](http://stylelint.io/) with [WordPress standards](https://github.com/stylelint/stylelint-config-wordpress) preconfigured (overrideable in `config.js`). 19 | * Compilation of Sass styles with [libSass](http://sass-lang.com/libsass). 20 | * Post-processing through [PostCSS](https://github.com/postcss/postcss). Plugins included by default: 21 | * [Autoprefixer](https://github.com/postcss/autoprefixer) to add browser vendor prefixes; 22 | * [CSS-MQPacker](https://www.npmjs.com/package/css-mqpacker) to regroup media queries; 23 | * [Perfectionist](https://github.com/ben-eb/perfectionist) to prettify generated CSS. 24 | * Check browser support of generated CSS against Autoprefixer settings through [doiuse](https://github.com/anandthakker/doiuse). 25 | * Minification through [cssnano](http://cssnano.co/) (both minified & non-minified version are usable). 26 | * Sourcemaps for easy debugging provided by [gulp-sourcemaps](https://www.npmjs.com/package/gulp-sourcemaps). 27 | 28 | ### Scripts 29 | 30 | * Linting through [JSHint](http://jshint.com/) with [WordPress standards](https://develop.svn.wordpress.org/trunk/.jshintrc) preconfigured. 31 | * Minification through [UglifyJS](http://lisperator.net/uglifyjs/) (both minified & non-minified version are usable). 32 | 33 | ### Images 34 | 35 | * Optimization through [ImageMin](https://github.com/imagemin/imagemin). 36 | 37 | ## Requirements 38 | 39 | The main requirements to be able to use this are: 40 | 41 | * [Node.js](https://nodejs.org/) - tested with 2.11.3 42 | * [gulp](http://gulpjs.com/) - tested with 3.9 43 | 44 | ## Installation 45 | 46 | The contents of this repository are meant to be dropped inside the root folder of an existing project, so that the `gulpfile.js` resides at the root of the project. 47 | 48 | The file `gulp/config.js` should be modified so that it fits the project's folder structure. 49 | 50 | To add the dependencies that are needed for the individual gulp tasks to your project's `package.json` ([which should already exist](https://docs.npmjs.com/cli/init)), run the following command in your project's root folder: 51 | 52 | ``` 53 | cat gulp/dependencies | xargs npm install --save-dev 54 | ``` 55 | 56 | The file `gulp/dependencies` can be safely deleted after this operation, it is no longer needed. 57 | 58 | ## Usage 59 | 60 | To get an overview of the available tasks that are provided with this starter setup, run the following command in your project's root folder: 61 | 62 | ``` 63 | gulp help 64 | ``` 65 | 66 | The default task that will run when no specific option is provided is the `watch` task. 67 | 68 | ## Special Notes 69 | 70 | ### style.css 71 | 72 | The stylesheet gets compiled to a `style.css` & `style.min.css`, but they do not get moved to the theme root folder. 73 | 74 | Although WordPress requires a file called `style.css` inside the theme root folder, this goes against several best practices. That's why this setup will provide both minified & non-minified versions of the stylesheet in the proper assets folder (defaults to `assets/styles/style.css`). 75 | 76 | You should provide a stub file inside the theme's root folder with the necessary theme metadata comments, so that WordPress correctly recognizes the theme. 77 | 78 | To load the correct stylesheet on the frontend, add the following code to your theme: 79 | ```PHP 80 | add_filter( 'stylesheet_uri', 'wpdc_stylesheet_uri', 10, 2 ); 81 | /** 82 | * Modify location of main stylesheet 83 | * N.B.: style.css in the theme's root is still needed to provide WordPress 84 | * with the necessary metadata about the theme 85 | */ 86 | function wpdc_stylesheet_uri( $stylesheet_uri, $stylesheet_dir_uri ) { 87 | 88 | // TODO: Adapt this to your theme's folder structure 89 | $folder = '/assets/styles/'; 90 | 91 | // TODO: Adapt this to your theme's filenames 92 | $name = 'style'; 93 | 94 | $suffix = defined( SCRIPT_DEBUG ) ? '.css' : '.min.css'; 95 | 96 | return $stylesheet_dir_uri . $folder . $name . $suffix; 97 | } 98 | ``` 99 | 100 | ## Known Issues 101 | 102 | * `gulp dist` has not been completed yet. 103 | 104 | * There currently seems to be a race condition between Sass & PostCSS. Thanks to @iCaspar for the testing & debugging. 105 | 106 | * If you are getting errors while pulling in the dependencies as described in the section "Installation", make sure that you are running a current version of `npm`. The latest stable one should always be correct, as of this writing, the code has been tested with version 3.3.9. 107 | To get the current version, type the command `npm -v` at your command-line. 108 | It is also a good idea to clear your npm's cache, as it might contain old versions of the packages we're trying to use. To clear your cache, type `npm cache clean` at your command-line. 109 | -------------------------------------------------------------------------------- /gulp/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * config.js - Configuration file for the gulp task runner. 3 | * 4 | * For a basic project, the configuration file is the only file that should need 5 | * to be modified to get a working gulp setup. 6 | * 7 | * @package WPDC gulp Starter 8 | * @since 1.0.0 9 | * @author Alain Schlesser 10 | * @link http://wpdevelopersclub.com/ 11 | * @license GNU General Public License 2.0+ 12 | * @copyright 2015 WP Developers Club 13 | */ 14 | 15 | /* ----------------------------------------------------------------------------- 16 | * General Settings 17 | * ----------------------------------------------------------------------------- 18 | * 19 | * Define your main folders here. 20 | * 21 | * Initial configuration is as follows: 22 | * You develop your source files in `$src`, gulp builds and watches everything 23 | * in `$dest` and your production files are built in `$dist` when you run 24 | * `gulp dist. 25 | */ 26 | 27 | /** 28 | * Name of the project. 29 | * This is used to build the package in `$dist`. 30 | * @type {String} 31 | */ 32 | var project = 'projectname'; 33 | 34 | /** 35 | * Location of your source files. 36 | * This is relative to the `gulpfile.js` file. 37 | * @type {String} 38 | */ 39 | var src = './'; 40 | 41 | /** 42 | * Target Location of your built files. 43 | * This is relative to the `gulpfile.js` file. 44 | * @type {String} 45 | */ 46 | var dest = './'; 47 | 48 | /** 49 | * Target location of your library files. 50 | * This is relative to the `gulpfile.js` file. 51 | * @type {String} 52 | */ 53 | var lib = dest + 'lib/'; 54 | 55 | /** 56 | * Target location of your distribution files. 57 | * This is relative to the `gulpfile.js` file. 58 | * @type {String} 59 | */ 60 | var dist = './dist/' + project; 61 | 62 | /* ----------------------------------------------------------------------------- 63 | * Folder Structure 64 | * ----------------------------------------------------------------------------- 65 | * 66 | * Configure folder structure details here. 67 | * 68 | * For basic projects, you will only need to check the different `xxxSubDir` 69 | * entries, the rest should provide sane defaults. 70 | */ 71 | 72 | /** 73 | * Name of the folder that regroups the static assets. 74 | * @type {String} 75 | */ 76 | var assetsDir = 'assets/'; 77 | 78 | /* ------------------------------ Stylesheets ------------------------------- */ 79 | 80 | /** 81 | * Name of the folder that regroups the cascading stylesheets. 82 | * @type {String} 83 | */ 84 | var styleSubDir = 'styles'; 85 | 86 | /** 87 | * Possible extensions for the cascading stylesheets. 88 | * @type {String} 89 | */ 90 | var styleExts = '{sass,scss,css}'; 91 | 92 | /* ------------------------------ JavaScript -------------------------------- */ 93 | 94 | /** 95 | * Name of the folder that regroups the JavaScript files. 96 | * @type {String} 97 | */ 98 | var scriptSubDir = 'scripts'; 99 | 100 | /** 101 | * Possible extensions for the JavaScript files. 102 | * @type {String} 103 | */ 104 | var scriptExts = 'js'; 105 | 106 | /* -------------------------------- Images ---------------------------------- */ 107 | 108 | /** 109 | * Name of the folder that regroups the images. 110 | * @type {String} 111 | */ 112 | var imageSubDir = 'images'; 113 | 114 | /** 115 | * Possible extensions for the image files. 116 | * @type {String} 117 | */ 118 | var imageExts = '{jpg,jpeg,gif,png,svg,ico}'; 119 | 120 | /* ----------------------------------------------------------------------------- 121 | * Configuration 122 | * ----------------------------------------------------------------------------- 123 | * 124 | * Here comes the actual configuration that is exported. 125 | * 126 | * The settings in here allow you to tweak the behavior of some of the modules 127 | * that are used by gulp. 128 | * 129 | * For basic projects, you will not need to modify anything below. 130 | */ 131 | 132 | var styleDir = assetsDir + styleSubDir; 133 | var scriptDir = assetsDir + scriptSubDir; 134 | var imageDir = assetsDir + imageSubDir; 135 | 136 | module.exports = { 137 | 138 | /* ---------------------------- General Config ------------------------------ */ 139 | 140 | project : project, 141 | src : src, 142 | dest : dest, 143 | build : dest, 144 | lib : lib, 145 | dist : dist, 146 | assetsDir : assetsDir, 147 | 148 | /* ----------------------------- Stylesheets -------------------------------- */ 149 | 150 | styles: { 151 | exts: styleExts, 152 | // ignore _partials 153 | buildSrc: [ 154 | src + styleDir + '/**/*.' + styleExts, 155 | '!' + src + styleDir + '/**/_*.' + styleExts 156 | ], 157 | dest: dest + assetsDir, 158 | watchSrc: [ 159 | src + styleDir + '/**/*.' + styleExts, 160 | '!' + src + styleDir + '/**/*.css' 161 | ], 162 | base: src + assetsDir, 163 | 164 | sassSettings: { 165 | style: 'expanded', 166 | sourceComments: 'map', 167 | imagePath: '/' + imageDir // Used by the image-url helper 168 | }, 169 | 170 | // Don't include cssnano, it is included automatically. 171 | postcssSettings: { 172 | processors: { 173 | 'autoprefixer': { 174 | browsers: [ 175 | 'last 2 versions', 176 | 'ie 9', 177 | 'ios 6', 178 | 'android 4' 179 | ] 180 | }, 181 | 'css-mqpacker': { 182 | sort: true 183 | }, 184 | 'perfectionist': { 185 | cascade: true, 186 | format: 'expanded', 187 | indentSize: 4, 188 | maxAtRuleLength: 80, 189 | maxSelectorLength: 80, 190 | maxValueLength: 80, 191 | sourcemap: true 192 | } 193 | }, 194 | lintSettings: { 195 | 'rules': { 196 | // Add overrides to the default WordPress CSS standard rules 197 | // here. 198 | // @see http://stylelint.io/ 199 | } 200 | } 201 | } 202 | }, 203 | 204 | /* ------------------------------ JavaScript -------------------------------- */ 205 | 206 | scripts: { 207 | exts: scriptExts, 208 | // Avoid recursive min.min.min.js 209 | buildSrc: [ 210 | src + scriptDir + '/**/*.' + scriptExts, 211 | '!' + src + scriptDir + '/**/*.min.' + scriptExts 212 | ], 213 | dest: dest + assetsDir, 214 | watchSrc: src + scriptDir + '/**/*.' + scriptExts, 215 | base: src + assetsDir 216 | }, 217 | 218 | /* -------------------------------- Images ---------------------------------- */ 219 | 220 | images: { 221 | exts: imageExts, 222 | buildSrc: src + imageDir + '/**/*.' + imageExts, 223 | dest: dest + assetsDir, 224 | watchSrc: src + imageDir + '/**/*.' + imageExts, 225 | base: src + assetsDir, 226 | imageminSettings: { 227 | optimizationLevel: 7 228 | , progressive: true 229 | , interlaced: true 230 | } 231 | }, 232 | 233 | /* --------------------------------- Clean ---------------------------------- */ 234 | 235 | clean: { 236 | src: '[' + dest + '**/.DS_Store' 237 | // An example of how to add files to be deleted 238 | // ',' + dest + 'tmp/**/*' 239 | + ']' 240 | } 241 | }; 242 | -------------------------------------------------------------------------------- /gulp/dependencies: -------------------------------------------------------------------------------- 1 | autoprefixer 2 | css-mqpacker 3 | cssnano 4 | del 5 | gulp 6 | gulp-changed 7 | gulp-filter 8 | gulp-imagemin 9 | gulp-jshint 10 | gulp-notify 11 | gulp-postcss 12 | gulp-rename 13 | gulp-sass 14 | gulp-sourcemaps 15 | gulp-task-listing 16 | gulp-uglify 17 | gulp-util 18 | perfectionist 19 | postcss-reporter 20 | require-dir 21 | stylelint 22 | stylelint-config-wordpress 23 | -------------------------------------------------------------------------------- /gulp/tasks/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * build.js - Launch individual tasks that are necessary for a build. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'build', [ 'images', 'scripts', 'styles' ] ); 17 | -------------------------------------------------------------------------------- /gulp/tasks/clean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * clean.js - Clean out junk files after build. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'clean', [ 'build' ], function ( cb ) { 17 | 18 | var del = require( 'del' ); 19 | var config = require( '../config' ); 20 | 21 | del( config.clean.src ); 22 | 23 | cb(); 24 | 25 | } ); 26 | -------------------------------------------------------------------------------- /gulp/tasks/default.js: -------------------------------------------------------------------------------- 1 | /** 2 | * default.js - Default task to get executed when gulp is run without arguments. 3 | * 4 | * The default task runs `watch` which launches an entire build cycle as its 5 | * dependent subtask. 6 | * 7 | * @package WPDC gulp Starter 8 | * @since 1.0.0 9 | * @author Alain Schlesser 10 | * @link http://wpdevelopersclub.com/ 11 | * @license GNU General Public License 2.0+ 12 | * @copyright 2015 WP Developers Club 13 | */ 14 | 15 | 'use strict'; 16 | 17 | var gulp = require( 'gulp' ); 18 | var gutil = require( 'gulp-util' ); 19 | 20 | gutil.log( 'No task provided, launching default task.' ); 21 | gutil.log( 'Type "gulp help" to get a list of the available tasks.' ); 22 | 23 | gulp.task( 'default', [ 'watch' ] ); 24 | -------------------------------------------------------------------------------- /gulp/tasks/dist-copy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dist-copy.js - Copy all the files to the `$dist` folder. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'dist-copy', [ 'dist-wipe' ], function ( cb ) { 17 | 18 | var config = require( '../config' ); 19 | 20 | gulp.src( [ config.build + '**/*' ] ) 21 | .pipe( gulp.dest( config.dist ) ); 22 | 23 | cb(); 24 | 25 | } ); 26 | -------------------------------------------------------------------------------- /gulp/tasks/dist-images.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dist-images.js - Optimize images in place. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'dist-images', [ 'dist-styles' ], function () { 17 | 18 | var imagemin = require( 'gulp-imagemin' ); 19 | var config = require( '../config' ); 20 | 21 | return gulp.src( [ config.dist + "**/*." + config.imageExts ] ) 22 | .pipe( imagemin( config.images.imageminSettings ) ) 23 | .pipe( gulp.dest( config.dist ) ); 24 | 25 | } ); 26 | -------------------------------------------------------------------------------- /gulp/tasks/dist-styles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dist-styles.js - Optimize stylesheets for distribution. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'dist-styles', [ 'dist-copy' ], function () { 17 | 18 | } ); 19 | -------------------------------------------------------------------------------- /gulp/tasks/dist-wipe.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dist-wipe.js - Totally wipe the contents of the distribution folder after 3 | * doing a clean build. 4 | * 5 | * @package WPDC gulp Starter 6 | * @since 1.0.0 7 | * @author Alain Schlesser 8 | * @link http://wpdevelopersclub.com/ 9 | * @license GNU General Public License 2.0+ 10 | * @copyright 2015 WP Developers Club 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var gulp = require( 'gulp' ); 16 | 17 | gulp.task( 'dist-wipe', [ 'clean' ], function ( cb ) { 18 | 19 | var del = require( 'del' ); 20 | var config = require( '../config' ); 21 | 22 | del( config.dist, cb ); 23 | 24 | } ); 25 | -------------------------------------------------------------------------------- /gulp/tasks/dist.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dist.js - Package everything up for distribution. 3 | * 4 | * `gulp dist` creates a clean distribution package under `$dist` after running 5 | * build, clean, and wipe in sequence. 6 | * 7 | * @package WPDC gulp Starter 8 | * @since 1.0.0 9 | * @author Alain Schlesser 10 | * @link http://wpdevelopersclub.com/ 11 | * @license GNU General Public License 2.0+ 12 | * @copyright 2015 WP Developers Club 13 | */ 14 | 15 | 'use strict'; 16 | 17 | var gulp = require( 'gulp' ); 18 | 19 | gulp.task( 'dist', [ 'dist-images' ] ); 20 | -------------------------------------------------------------------------------- /gulp/tasks/help.js: -------------------------------------------------------------------------------- 1 | /** 2 | * help.js - Print a list of available gulp tasks. 3 | * 4 | * The output is divided into main tasks and subtasks. Subtasks are identified 5 | * by having either a `-`, a `_` or a `:` in their task name. 6 | * 7 | * @package WPDC gulp Starter 8 | * @since 1.0.0 9 | * @author Alain Schlesser 10 | * @link http://wpdevelopersclub.com/ 11 | * @license GNU General Public License 2.0+ 12 | * @copyright 2015 WP Developers Club 13 | */ 14 | 15 | 'use strict'; 16 | 17 | var gulp = require( 'gulp' ); 18 | var taskListing = require( 'gulp-task-listing' ); 19 | 20 | gulp.task( 'help', taskListing ); 21 | -------------------------------------------------------------------------------- /gulp/tasks/images-optimize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * images-optimize.js - Copy and optimize images. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'images-optimize', function () { 17 | 18 | var changed = require( 'gulp-changed' ); 19 | var imagemin = require( 'gulp-imagemin' ); 20 | var config = require( '../config' ).images; 21 | 22 | return gulp.src( config.buildSrc, { base: config.base } ) 23 | .pipe( changed( config.dest ) ) 24 | .pipe( imagemin( config.imageminSettings ) ) 25 | .pipe( gulp.dest( config.dest ) ); 26 | 27 | } ); 28 | -------------------------------------------------------------------------------- /gulp/tasks/images.js: -------------------------------------------------------------------------------- 1 | /** 2 | * images.js - Handle images. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'images', [ 'images-optimize' ] ); 17 | -------------------------------------------------------------------------------- /gulp/tasks/scripts-lint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * scripts-lint.js - Run the JavaScript files through a linter. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'scripts-lint', function () { 17 | 18 | var jshint = require( 'gulp-jshint' ); 19 | var changed = require( 'gulp-changed' ); 20 | var handleErrors = require( '../util/handleErrors' ); 21 | var config = require( '../config' ).scripts; 22 | 23 | return gulp.src( config.buildSrc ) 24 | .pipe( changed( config.dest ) ) 25 | .pipe( jshint( '.jshintrc' ) ) 26 | .on( 'error', handleErrors ) 27 | .pipe( jshint.reporter( 'default' ) ) 28 | .on( 'error', handleErrors ); 29 | 30 | } ); 31 | -------------------------------------------------------------------------------- /gulp/tasks/scripts-uglify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * scripts-uglify.js - Minify JavaScript files. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'scripts-uglify', function () { 17 | 18 | var rename = require( 'gulp-rename' ); 19 | var uglify = require( 'gulp-uglify' ); 20 | var config = require( '../config' ).scripts; 21 | 22 | return gulp.src( config.buildSrc, { base: config.base } ) 23 | .pipe( uglify() ) 24 | .pipe( rename( { extname: '.min.js' } ) ) 25 | .pipe( gulp.dest( config.dest ) ); 26 | 27 | } ); 28 | -------------------------------------------------------------------------------- /gulp/tasks/scripts.js: -------------------------------------------------------------------------------- 1 | /** 2 | * scripts.js - Handle JavaScript files. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'scripts', [ 'scripts-lint', 'scripts-uglify' ] ); 17 | -------------------------------------------------------------------------------- /gulp/tasks/styles-lint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * styles-lint.js - Run CSS through a linter. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'styles-lint', function () { 17 | 18 | var filter = require( 'gulp-filter' ); 19 | var postcss = require( 'gulp-postcss' ); 20 | var stylelint = require( 'stylelint' ); 21 | var reporter = require( 'postcss-reporter' ); 22 | var configWordPress = require( 'stylelint-config-wordpress' ); 23 | var mergeRecursive = require( '../util/mergeRecursive' ); 24 | var config = require( '../config' ).styles; 25 | 26 | var sassFilter = filter( [ '**/*.sass', '**/*.scss' ], { restore: false } ); 27 | 28 | config.postcssSettings.lintSettings.rules = mergeRecursive( 29 | configWordPress.rules, 30 | config.postcssSettings.lintSettings.rules 31 | ); 32 | 33 | return gulp.src( config.buildSrc, { base: config.base } ) 34 | 35 | .pipe( sassFilter ) 36 | 37 | .pipe( postcss( [ 38 | stylelint( config.postcssSettings.lintSettings ), 39 | reporter( { clearMessages: true } ) 40 | ] ) ); 41 | 42 | } ); 43 | -------------------------------------------------------------------------------- /gulp/tasks/styles-postcss.js: -------------------------------------------------------------------------------- 1 | /** 2 | * styles-postcss.js - Process stylesheets with PostCSS. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'styles-postcss', function () { 17 | 18 | var gutil = require( 'gulp-util' ); 19 | var filter = require( 'gulp-filter' ); 20 | var rename = require( 'gulp-rename' ); 21 | var postcss = require( 'gulp-postcss' ); 22 | var sourcemaps = require( 'gulp-sourcemaps' ); 23 | var cssnano = require( 'cssnano' ); 24 | var config = require( '../config' ).styles; 25 | var handleErrors = require( '../util/handleErrors' ); 26 | 27 | var cssFilter = filter( [ '**/*.css', '!**/*.min.css' ], { restore: false } ); 28 | 29 | function loadModules ( processorsConfig ) { 30 | var processors = []; 31 | for ( var processor in processorsConfig ) { 32 | var processorConfig = processorsConfig[ processor ]; 33 | var instance = null; 34 | 35 | gutil.log( 'Loading PostCSS Module: ' + processor ); 36 | instance = require( processor ); 37 | processors.push( instance( processorConfig ) ); 38 | } 39 | return processors; 40 | } 41 | 42 | return gulp.src( config.buildSrc, { base: config.base } ) 43 | 44 | .pipe( cssFilter ) 45 | 46 | .pipe( sourcemaps.init() ) 47 | 48 | .pipe( postcss( loadModules( config.postcssSettings.processors ) ) ) 49 | .on( 'error', handleErrors ) 50 | 51 | .pipe( gulp.dest( config.dest ) ) 52 | 53 | .pipe( postcss( [ cssnano ] ) ) 54 | .pipe( rename( { extname: '.min.css' } ) ) 55 | .pipe( gulp.dest( config.dest ) ) 56 | 57 | .pipe( sourcemaps.write( './' ) ); 58 | 59 | } ); 60 | -------------------------------------------------------------------------------- /gulp/tasks/styles-sass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * styles-sass.js - Compile sass source files and generate CSS. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'styles-sass', function ( cb ) { 17 | 18 | var sass = require( 'gulp-sass' ); 19 | var filter = require( 'gulp-filter' ); 20 | var rename = require( 'gulp-rename' ); 21 | var config = require( '../config' ).styles; 22 | var handleErrors = require( '../util/handleErrors' ); 23 | 24 | var sassFilter = filter( [ '**/*.sass', '**/*.scss' ], { restore: false } ); 25 | 26 | gulp.src( config.buildSrc, { base: config.base } ) 27 | 28 | .pipe( sassFilter ) 29 | 30 | .pipe( sass( config.sassSettings ) ) 31 | .on( 'error', handleErrors ) 32 | 33 | .pipe( gulp.dest( config.dest ) ); 34 | 35 | cb(); 36 | 37 | } ); 38 | -------------------------------------------------------------------------------- /gulp/tasks/styles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * styles.js - Handle stylesheets. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var gulp = require( 'gulp' ); 15 | 16 | gulp.task( 'styles', [ 'styles-lint', 'styles-sass', 'styles-postcss' ] ); -------------------------------------------------------------------------------- /gulp/tasks/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * watch.js - Watch for file changes to relaunch necessary tasks. 3 | * 4 | * The default task runs `watch` which launches an entire build cycle as its 5 | * dependent subtask. 6 | * 7 | * @package WPDC gulp Starter 8 | * @since 1.0.0 9 | * @author Alain Schlesser 10 | * @link http://wpdevelopersclub.com/ 11 | * @license GNU General Public License 2.0+ 12 | * @copyright 2015 WP Developers Club 13 | */ 14 | 15 | 'use strict'; 16 | 17 | var gulp = require( 'gulp' ); 18 | 19 | gulp.task( 'watch', [ 'build' ], function () { 20 | 21 | var config = require( '../config' ); 22 | 23 | gulp.watch( config.styles.watchSrc, [ 'styles' ] ); 24 | gulp.watch( config.scripts.watchSrc, [ 'scripts' ] ); 25 | gulp.watch( config.images.watchSrc, [ 'images' ] ); 26 | 27 | } ); 28 | -------------------------------------------------------------------------------- /gulp/util/handleErrors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * handleErrors.js - Error handler that sends notification and keeps gulp 3 | * running. 4 | * 5 | * Depending on the OS that gulp is run on, the `notify` command might have 6 | * different run-time dependencies to actually show a real notification. 7 | * @see https://www.npmjs.com/package/gulp-notify#requirements 8 | * 9 | * @package WPDC gulp Starter 10 | * @since 1.0.0 11 | * @author Alain Schlesser 12 | * @link http://wpdevelopersclub.com/ 13 | * @license GNU General Public License 2.0+ 14 | * @copyright 2015 WP Developers Club 15 | */ 16 | 17 | var notify = require( 'gulp-notify' ); 18 | 19 | module.exports = function () { 20 | 21 | var args = Array.prototype.slice.call( arguments ); 22 | 23 | // Send error to notification center with gulp-notify. 24 | notify.onError( { 25 | title: "Compile Error", 26 | message: "<%= error %>" 27 | } ).apply( this, args ); 28 | 29 | // Keep gulp from hanging on this task. 30 | this.emit( 'end' ); 31 | }; 32 | -------------------------------------------------------------------------------- /gulp/util/mergeRecursive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * mergeRecursive.js - Merge two objects' properties recursively. 3 | * 4 | * @package WPDC gulp Starter 5 | * @since 1.0.0 6 | * @author Alain Schlesser 7 | * @link http://wpdevelopersclub.com/ 8 | * @license GNU General Public License 2.0+ 9 | * @copyright 2015 WP Developers Club 10 | */ 11 | 12 | function MergeRecursive( objectA, objectB ) { 13 | 14 | for ( var p in objectB ) { 15 | try { 16 | // Property in destination object set; update its value. 17 | if ( objectB[ p ].constructor == Object ) { 18 | objectA[ p ] = MergeRecursive( objectA[ p ], objectB[ p ] ); 19 | 20 | } else { 21 | objectA[ p ] = objectB[ p ]; 22 | 23 | } 24 | 25 | } catch ( e ) { 26 | objectA[ p ] = objectB[ p ]; 27 | } 28 | } 29 | 30 | return objectA; 31 | } 32 | 33 | module.exports = MergeRecursive; 34 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * gulpfile.js - Entry point for the gulp task runner. 3 | * 4 | * `gulpfile.js` is the configuration file that gulp tries to read per default. 5 | * 6 | * Rather than manage one giant configuration file responsible for creating 7 | * multiple tasks, each task has been broken out into its own file in 8 | * `gulp/tasks`. 9 | * 10 | * Any files in that directory get automatically required below. 11 | * 12 | * To add a new task, simply add a new task file that directory. 13 | * 14 | * gulp/tasks/default.js specifies the default set of tasks to run when you run 15 | * `gulp`. 16 | * 17 | * @package WPDC gulp Starter 18 | * @since 1.0.0 19 | * @author Alain Schlesser 20 | * @link http://wpdevelopersclub.com/ 21 | * @license GNU General Public License 2.0+ 22 | * @copyright 2015 WP Developers Club 23 | */ 24 | 25 | var gulp = require( 'gulp' ); 26 | var requireDir = require( 'require-dir' ); 27 | 28 | // Require all tasks in gulp/tasks, including subfolders 29 | requireDir( './gulp/tasks', { recurse: true } ); 30 | --------------------------------------------------------------------------------