Skip to content

Instantly share code, notes, and snippets.

@typeoneerror
Created June 17, 2014 17:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typeoneerror/19152acb1070b024605f to your computer and use it in GitHub Desktop.
Save typeoneerror/19152acb1070b024605f to your computer and use it in GitHub Desktop.
// TODO: watch for renaming of files or adding/deleting files
// Requirements
var gulp = require('gulp')
, changed = require('gulp-changed')
, clean = require('gulp-clean')
, coffee = require('gulp-coffee')
, compass = require('gulp-compass')
, concat = require('gulp-concat')
, minifyCSS = require('gulp-minify-css')
, uglify = require('gulp-uglify')
, gutil = require('gulp-util')
, imagemin = require('gulp-imagemin')
, livereload = require('gulp-livereload')
, plumber = require('gulp-plumber')
, sequence = require('run-sequence')
, argv = require('yargs').argv
, fs = require('fs')
, path = require('path')
, util = require('util')
, pkg = require('./package.json');
// Determine environment, dev is default
// Other command line settings as well
var isProd = argv.p || argv.prod || false
, isDev = isProd ? false : true
, shouldReload = argv.l || argv.live || false;
// Load config file if it exists
var config_file = './config.json';
if (fs.existsSync(config_file))
{
var config = require(config_file);
gutil.log('Using config', gutil.colors.magenta(fs.realpathSync(config_file)));
}
else
{
gutil.log('No config.json file found, continuing with defaults...');
}
// Flat directories
var dirs = {
styles: './source/styles'
, scripts: './source/scripts'
, vendor_scripts: './source/vendor'
, build: './source/build'
, images: './source/images'
, fonts: './source/fonts'
};
// Path varieties
var js_files = '/**/*.{js,map}'
, image_files = '/**/*'
, scripts_dir = '/scripts'
, styles_dir = '/styles'
, vendor_dir = '/vendor'
, images_dir = '/images';
// Expanded paths
var paths = {
styles: dirs.styles + '/**/*.scss'
, styles_compiled: dirs.build + styles_dir
, scripts: dirs.scripts + '/**/*.coffee'
, scripts_compiled: dirs.build + scripts_dir
, images: dirs.images + '/**/*'
, images_compiled: dirs.build + images_dir
, vendor_scripts: dirs.vendor_scripts + js_files
, theme_dir: 'wordpress/wp-content/themes/' + pkg.name
};
// Handle piping errors with a message
var handleError = function(err) {
gutil.log(gutil.colors.yellow(err));
if (this.emit)
{
log("emit");
this.emit('end');
}
};
// Log a status message
var log = function(msg)
{
gutil.log(gutil.colors.magenta(msg));
}
// Display a finished message and wrap up stream with a callback
var complete = function(callback, msg, error) {
error = error || null;
log(msg);
if (callback)
{
callback(error);
}
};
// Cleans the compiled javascript folders
gulp.task('clean-scripts', function() {
var cleanPaths = [paths.scripts_compiled + js_files, paths.theme_dir + scripts_dir + js_files];
return gulp.src(cleanPaths, {read: false})
.pipe(clean())
.on('error', handleError)
.on('end', function(){
log('"clean-scripts" task complete');
});
});
// Compile coffeescript files from source
gulp.task('coffee', function() {
return gulp.src(paths.scripts)
.pipe(coffee({bare: true}))
.pipe(gulp.dest(paths.scripts_compiled))
.pipe(uglify())
.pipe(gulp.dest(paths.theme_dir + scripts_dir))
.on('error', handleError)
.on('end', function(){
log('"coffee" task complete')
});
});
// Copy javascript vendor files to the build dir and theme dir
gulp.task('copy-vendor', function() {
return gulp.src(dirs.vendor_scripts + '/**/*')
.pipe(gulp.dest(paths.scripts_compiled + vendor_dir))
.pipe(gulp.dest(paths.theme_dir + scripts_dir + vendor_dir))
.on('error', handleError)
.on('end', function() {
log('"copy-vendor" task complete');
});
});
// Copy javascript files from compiled dir to theme dir
gulp.task('copy-js', ['copy-vendor'], function() {
return gulp.src(dirs.scripts + '/**/*.js')
.pipe(gulp.dest(paths.scripts_compiled))
.pipe(uglify())
.pipe(gulp.dest(paths.theme_dir + scripts_dir))
.on('error', handleError)
.on('end', function() {
log('"copy-js" task complete');
});
});
// Concatenate javascript files if setup in config.json file
gulp.task('concat-js', function(cb) {
if (config && config.concat)
{
var outputFiles = config.concat
, dest = paths.theme_dir + scripts_dir
, err = null
, numFiles = 0
, counter = 0;
for (var file in outputFiles)
{
numFiles++;
var files = outputFiles[file]
, outputFile = util.format('%s.js', file);
gutil.log(util.format('Concatenating "%s" into %s...', file, outputFile));
files = files.map(function(file) {
var suffixPattern = '.js'
, suffix = file.indexOf(suffixPattern, file.length - suffixPattern.length) !== -1 ? '' : suffixPattern
, path = util.format('%s/%s%s', paths.scripts_compiled, file, suffix);
gutil.log(util.format('\tAdding %s', path));
if (!fs.existsSync(path))
{
err = [path + ' didn\'t exist'];
return;
}
return path;
});
if (err)
{
handleError(err);
complete(cb, 'Error running "concat-js"', err);
return;
}
gulp.src(files)
.pipe(concat(outputFile))
.pipe(gulp.dest(paths.scripts_compiled))
.pipe(uglify())
.pipe(gulp.dest(dest))
.on('error', handleError)
.on('end', function() {
counter++;
if (counter === numFiles)
{
complete(cb, '"concat-js" task complete (prod)');
}
});
}
}
else
{
complete(cb, '"concat-js" task complete (dev)');
}
});
// Compiles coffeescript files and concatenates without updating vendor scripts
gulp.task('scripts-light', function(cb) {
sequence('coffee', 'concat-js', function() {
complete(cb, '"scripts-light" task complete');
})
});
// Compiles coffeescript files, copies vendor scripts, and concatenates
gulp.task('scripts', function(cb) {
sequence('clean-scripts', 'coffee', 'copy-js', 'concat-js', function() {
complete(cb, '"scripts" task complete');
});
});
// Clean built images folders
gulp.task('clean-images', function(cb){
var cleanPaths = [paths.images_compiled + image_files, paths.theme_dir + images_dir + image_files];
return gulp.src(cleanPaths, {read: false})
.pipe(clean())
.on('error', handleError)
.on('end', function(){
log('"clean-images" task complete');
})
});
// Copies and runs tasks on images
gulp.task('images', function(cb) {
var build_output = paths.images_compiled
, prod_output = paths.theme_dir + images_dir;
gulp.src(paths.images)
.pipe(changed(build_output))
.pipe(gulp.dest(build_output))
.pipe(imagemin({
optimizationLevel: 5
, pngquant: false // png
, interlaced: false // gif
, progressive: false // jpg
}))
.pipe(gulp.dest(prod_output))
.on('error', handleError)
.on('end', function() {
complete(cb, '"images" task complete')
})
});
// Cleans compiled css files
gulp.task('clean-styles', function(cb) {
gulp.src(paths.styles_compiled + '/**/*.css', {read: false})
.pipe(clean())
.on('error', handleError)
.on('end', function() {
complete(cb, '"clean-styles" task complete')
});
});
// Compiles sass files to css
gulp.task('styles', ['clean-styles'], function() {
var compass_options = {
config_file: 'config.rb'
, bundle_exec: true
, project: path.join(__dirname)
, sass: 'source/styles'
, css: 'source/build/styles'
, font: 'source/fonts'
};
var minify_options = {
};
return gulp.src(paths.styles)
.pipe(plumber())
.pipe(compass(compass_options))
.pipe(gulp.dest(paths.styles_compiled))
.pipe(minifyCSS(minify_options))
.pipe(gulp.dest(paths.theme_dir))
.on('error', function(error) {
// let gulp show the error
})
.on('end', function() {
log('"styles" task complete');
});
});
// Clean everything
gulp.task('clean', ['clean-scripts', 'clean-styles', 'clean-images'], function(cb) {
complete(cb, '"clean" task complete');
});
// Note when files change
var handleWatchEvent = function(event) {
console.log('File ' + path.basename(event.path) + ' was ' + event.type + ', running tasks...');
};
// Watch for changes to coffeescript and sass and recompile on the fly
gulp.task('watch', function(cb) {
log('Watching for changes to scripts, styles, and images');
// Run full scripts if vendor or config changes
gulp.watch([dirs.vendor_scripts + '/**/*.js', 'config.json'], ['scripts'])
.on('change', handleWatchEvent);
// Run light scripts if only app source scripts change
gulp.watch(paths.scripts, ['scripts-light'])
.on('change', handleWatchEvent);
// If sass files are changes, compile them
gulp.watch(paths.styles, ['styles'])
.on('change', handleWatchEvent);
// If images change, compress and copy them
gulp.watch(paths.images, ['images'])
.on('change', handleWatchEvent);
// Start a live reload instance if requested
// Works with Chrome's LiveReload plugin to refresh the changed assets
if (shouldReload)
{
var server = livereload();
gulp.watch([paths.theme_dir + '/**/*.css', paths.theme_dir + images_dir + image_files], function(event) {
server.changed(event.path);
});
}
});
// Default task runs images task first then styles and scripts in parallel
gulp.task('default', function() {
sequence('clean-images', 'images', function() {
gulp.start('styles', 'scripts');
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment