Last active
February 5, 2019 15:58
-
-
Save umkasanki/4e71973b02dcce753bb2b394b25cd84d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-env node */ | |
// package vars | |
const pkg = require('./package.json'); | |
const webpack = require('webpack-stream'); | |
const gulp = require('gulp'); | |
// load all plugins in "devDependencies" into the variable $ | |
const $ = require('gulp-load-plugins')({ | |
pattern: ['*'], | |
scope: ['devDependencies'], | |
rename: { | |
'gulp-prettier': 'prettify' | |
} | |
}); | |
// error logging | |
const onError = err => { | |
$.notify.onError({ | |
title: 'Gulp', | |
subtitle: ['<%= error.relativePath %>', '<%= error.line %>'].join(':'), | |
message: '<%= error.messageOriginal %>', | |
open: 'file://<%= error.file %>', | |
onLast: true, | |
sound: 'Beep' | |
})(err); | |
}; | |
let currentCSSVersion = 0; | |
let currentJSVersion = 0; | |
// static assets version tasks | |
gulp.task('css-version', () => { | |
$.fancyLog('-> Change CSS version'); | |
return gulp | |
.src(pkg.paths.craftConfig + 'general.php') | |
.pipe( | |
$.replace(/'currentCSSVersion' => (\d+),/g, function(match, p1) { | |
p1++; | |
$.fancyLog('-> Changed currentCSSVersion to ' + p1); | |
currentCSSVersion = p1; | |
return "'currentCSSVersion' => " + p1 + ','; | |
}) | |
) | |
.pipe(gulp.dest(pkg.paths.craftConfig)); | |
}); | |
gulp.task('js-version', () => { | |
$.fancyLog('-> Change JS version'); | |
return gulp | |
.src(pkg.paths.craftConfig + 'general.php') | |
.pipe( | |
$.replace(/'currentJSVersion' => (\d+),/g, function(match, p1) { | |
p1++; | |
$.fancyLog('-> Changed currentJSVersion to ' + p1); | |
currentJSVersion = p1; | |
return "'currentJSVersion' => " + p1; | |
}) | |
) | |
.pipe(gulp.dest(pkg.paths.craftConfig)); | |
}); | |
// gulp clean-js | |
gulp.task('clean-js', () => { | |
return gulp.src([ | |
pkg.paths.build.js + '**/*.js', | |
pkg.paths.dist.js + '**/*.js' | |
], { read: false }).pipe($.clean()); | |
}); | |
// gulp clean-css | |
gulp.task('clean-css', () => { | |
return gulp.src([ | |
pkg.paths.build.css + '**/*', | |
pkg.paths.dist.css + '**/*' | |
], | |
{ read: false }).pipe($.clean()); | |
}); | |
// gulp browser-sync | |
gulp.task('browser-sync', function(cb) { | |
$.browserSync.init({ | |
proxy: { | |
target: pkg.urls.local | |
} | |
}); | |
cb(); | |
}); | |
// gulp prettify - prettier task | |
gulp.task('prettify', () => { | |
return gulp | |
.src(['*.js', 'src/**/*.js', 'src/scss/**/*.scss', '*yml', '*.json', '*md']) | |
.pipe($.prettify()) | |
.pipe(gulp.dest(file => file.base)); | |
}); | |
// gulp scss - build the scss to the build folder, including the required paths, and writing out a sourcemap | |
gulp.task( | |
'scss', | |
gulp.series('css-version', 'clean-css', () => { | |
$.fancyLog('-> Compiling scss'); | |
return ( | |
gulp | |
.src(pkg.paths.src.scss + pkg.vars.scssName) | |
.pipe($.sassGlob()) | |
.pipe($.plumber({ errorHandler: onError })) | |
.pipe($.sourcemaps.init({ loadMaps: true })) | |
.pipe( | |
$.sass({ | |
includePaths: [pkg.paths.scss, 'node_modules'] | |
}).on('error', $.sass.logError) | |
) | |
.pipe($.cached('sass_compile')) | |
.pipe($.autoprefixer()) | |
.pipe($.base64({ extensions: ['svg'], debug: true })) | |
.pipe($.sourcemaps.write('./')) | |
.pipe($.size({ gzip: true, showFiles: true })) | |
.pipe(gulp.dest(pkg.paths.build.css)) | |
); | |
}) | |
); | |
// gulp css - combine & minimize any distribution CSS into the public css folder, and add our banner to it | |
gulp.task( | |
'css', | |
gulp.series('scss', () => { | |
$.fancyLog('-> Building css'); | |
return ( | |
gulp | |
.src(pkg.globs.distCss) | |
.pipe($.plumber({ errorHandler: onError })) | |
.pipe($.newer({ dest: pkg.paths.dist.css + pkg.vars.siteCssName })) | |
.pipe($.print.default()) | |
.pipe($.sourcemaps.init({ loadMaps: true })) | |
// .pipe($.concat(currentCSSVersion + '.' + pkg.vars.siteCssName)) | |
.pipe($.rename({ suffix: '.min.' + currentCSSVersion })) | |
.pipe( | |
// $.if( | |
// process.env.NODE_ENV === 'production', | |
$.cssnano({ | |
discardComments: { | |
removeAll: true | |
}, | |
discardDuplicates: true, | |
discardEmpty: true, | |
minifyFontValues: true, | |
minifySelectors: true | |
}) | |
// ) | |
) | |
.pipe($.sourcemaps.write('./')) | |
.pipe($.size({ gzip: true, showFiles: true })) | |
.pipe(gulp.dest(pkg.paths.dist.css)) | |
.pipe($.filter('**/*.css')) | |
); | |
}) | |
); | |
// gulp js-babel - transpile our Javascript into the build directory | |
gulp.task( | |
'js-babel', | |
gulp.series('js-version', 'clean-js', () => { | |
$.fancyLog('-> Transpiling Javascript ...'); | |
return gulp | |
.src(pkg.globs.babelJs) | |
.pipe($.plumber({ errorHandler: onError })) | |
.pipe($.newer({ dest: pkg.paths.build.js })) | |
.pipe( | |
webpack({ | |
...require('./webpack.config.js'), | |
mode: process.env.NODE_ENV || 'development' | |
}) | |
) | |
.pipe(gulp.dest(pkg.paths.build.js)); | |
}) | |
); | |
// gulp js-inline - minimize the inline Javascript into _inlinejs in the templates path | |
gulp.task( | |
'js-inline', | |
gulp.series('js-babel', () => { | |
$.fancyLog('-> Copying inline js'); | |
return gulp | |
.src(pkg.globs.inlineJs) | |
.pipe($.plumber({ errorHandler: onError })) | |
.pipe( | |
$.if( | |
['*.js', '!*.min.js'], | |
$.newer({ dest: pkg.paths.templates + '_inlinejs', ext: '.min.js' }), | |
$.newer({ dest: pkg.paths.templates + '_inlinejs' }) | |
) | |
) | |
.pipe($.if(['*.js', '!*.min.js'], $.terser())) | |
.pipe($.if(['*.js', '!*.min.js'], $.rename({ suffix: '.min.' + currentJSVersion }))) | |
.pipe($.size({ gzip: true, showFiles: false })) | |
.pipe(gulp.dest(pkg.paths.templates + '_inlinejs')) | |
.pipe($.filter('**/*.js')); | |
}) | |
); | |
// gulp js - minimize any distribution Javascript into the public js folder, and add our banner to it | |
gulp.task( | |
'js', | |
gulp.series('js-inline', () => { | |
$.fancyLog('-> Building js'); | |
return ( | |
gulp | |
.src(pkg.globs.distJs) | |
.pipe($.plumber({ errorHandler: onError })) | |
.pipe( | |
$.if( | |
['*.js', '!*.min.js'], | |
$.newer({ dest: pkg.paths.dist.js, ext: '.min.js' }), | |
$.newer({ dest: pkg.paths.dist.js }) | |
) | |
) | |
.pipe($.if(['*.js', '!*.min.js'], $.terser())) | |
.pipe($.if(['*.js', '!*.min.js'], $.rename({ suffix: '.min.' + currentJSVersion }))) | |
.pipe($.stripComments()) | |
.pipe($.size({ gzip: true, showFiles: true })) | |
.pipe(gulp.dest(pkg.paths.dist.js)) | |
.pipe($.filter('**/*.js')) | |
); | |
}) | |
); | |
// Process data in an array synchronously, moving onto the n+1 item only after the nth item callback | |
function doSynchronousLoop(data, processData, done) { | |
if (data.length > 0) { | |
const loop = (data, i, processData, done) => { | |
processData(data[i], i, () => { | |
if (++i < data.length) { | |
loop(data, i, processData, done); | |
} else { | |
done(); | |
} | |
}); | |
}; | |
loop(data, 0, processData, done); | |
} else { | |
done(); | |
} | |
} | |
// Process the critical path CSS one at a time | |
function processCriticalCSS(element, i, callback) { | |
const criticalSrc = pkg.urls.critical + element.url; | |
const criticalDest = pkg.paths.templates + '_inlinecss/' + element.template + '_critical.min.css'; | |
let criticalWidth = 1440; | |
let criticalHeight = 1000; | |
if (element.template.indexOf('amp_') !== -1) { | |
criticalWidth = 375; | |
criticalHeight = 750; | |
} | |
$.fancyLog('-> Generating critical CSS: ' + $.chalk.cyan(criticalSrc) + ' -> ' + $.chalk.magenta(criticalDest)); | |
$.critical.generate( | |
{ | |
src: criticalSrc, | |
dest: criticalDest, | |
penthouse: { | |
timeout: 120000, | |
blockJSRequests: false, | |
forceInclude: pkg.globs.criticalWhitelist | |
}, | |
inline: false, | |
ignore: [], | |
css: [pkg.paths.dist.css + pkg.vars.siteCssName], | |
minify: true, | |
width: criticalWidth, | |
height: criticalHeight | |
}, | |
err => { | |
if (err) { | |
$.fancyLog($.chalk.magenta(err)); | |
} | |
callback(); | |
} | |
); | |
} | |
// gulp criticalcss - criticalcss css task | |
gulp.task( | |
'criticalcss', | |
gulp.series('css', callback => { | |
doSynchronousLoop(pkg.globs.critical, processCriticalCSS, () => { | |
// all done | |
callback(); | |
}); | |
}) | |
); | |
// gulp favicons-generate - favicons-generate task | |
gulp.task('favicons-generate', () => { | |
$.fancyLog('-> Generating favicons'); | |
return gulp | |
.src(pkg.paths.favicon.src) | |
.pipe( | |
$.favicons({ | |
appName: pkg.name, | |
appDescription: pkg.description, | |
developerName: pkg.author, | |
developerURL: pkg.urls.live, | |
background: '#FFFFFF', | |
path: pkg.paths.favicon.path, | |
url: pkg.site_url, | |
display: 'standalone', | |
orientation: 'portrait', | |
version: pkg.version, | |
logging: false, | |
online: false, | |
html: pkg.paths.build.html + 'favicons.html', | |
replace: true, | |
icons: { | |
android: false, // Create Android homescreen icon. `boolean` | |
appleIcon: true, // Create Apple touch icons. `boolean` | |
appleStartup: false, // Create Apple startup images. `boolean` | |
coast: true, // Create Opera Coast icon. `boolean` | |
favicons: true, // Create regular favicons. `boolean` | |
firefox: true, // Create Firefox OS icons. `boolean` | |
opengraph: false, // Create Facebook OpenGraph image. `boolean` | |
twitter: false, // Create Twitter Summary Card image. `boolean` | |
windows: true, // Create Windows 8 tile icons. `boolean` | |
yandex: true // Create Yandex browser icon. `boolean` | |
} | |
}) | |
) | |
.pipe(gulp.dest(pkg.paths.favicon.dest)); | |
}); | |
// gulp favicons - copy favicons task | |
gulp.task( | |
'favicons', | |
gulp.series('favicons-generate', () => { | |
$.fancyLog('-> Copying favicon.ico'); | |
return gulp | |
.src(pkg.globs.siteIcon) | |
.pipe($.size({ gzip: true, showFiles: true })) | |
.pipe(gulp.dest(pkg.paths.dist.base)); | |
}) | |
); | |
// gulp imagemin - imagemin task | |
gulp.task('imagemin', () => { | |
$.fancyLog('-> Minimizing images in ' + pkg.paths.src.img); | |
return gulp | |
.src(pkg.paths.src.img + '**/*.{png,jpg,jpeg,gif,svg}') | |
.pipe( | |
$.imagemin([ | |
$.imagemin.gifsicle({ interlaced: true }), | |
$.imagemin.optipng({ | |
optimizationLevel: 3 | |
}), | |
$.imagemin.jpegtran({ progressive: true }), | |
$.imagemin.svgo({ | |
removeViewBox: true | |
}) | |
]) | |
) | |
.pipe(gulp.dest(pkg.paths.dist.img)); | |
}); | |
// gulp fonts - copy fonts task | |
gulp.task('fonts', () => { | |
return gulp.src(pkg.globs.fonts).pipe(gulp.dest(pkg.paths.dist.fonts)); | |
}); | |
// gulp set-dev-node-env - set the node environment to development | |
gulp.task('set-dev-node-env', function(cb) { | |
$.fancyLog('-> Setting NODE_ENV to development'); | |
process.env.NODE_ENV = 'development'; | |
cb(); | |
}); | |
// gulp set-prod-node-env - set the node environment to production | |
gulp.task('set-prod-node-env', function(cb) { | |
$.fancyLog('-> Setting NODE_ENV to production'); | |
process.env.NODE_ENV = 'production'; | |
cb(); | |
}); | |
function reload(done) { | |
$.browserSync.reload(); | |
done(); | |
} | |
// gulp - default task | |
gulp.task( | |
'default', | |
gulp.series('set-dev-node-env', 'css', 'js', 'browser-sync', cb => { | |
$.fancyLog('-> Livereload listening for changes'); | |
gulp.watch('**/*.{scss,sass}', { cwd: pkg.paths.src.scss }, gulp.series('css', reload)); | |
gulp.watch('**/*.js', { cwd: pkg.paths.src.js }, gulp.series('js', reload)); | |
// gulp.watch('**/*.{png,jpg,jpeg,gif,svg}', { cwd: pkg.paths.src.img }, gulp.series('imagemin', reload)); | |
gulp | |
.watch('**/*.{html,twig}', { cwd: pkg.paths.templates }, gulp.series(() => { | |
return gulp.src(pkg.paths.templates).pipe($.plumber({ errorHandler: onError })); | |
}, reload)); | |
cb(); | |
}) | |
); | |
// gulp build - production build | |
gulp.task( | |
'build', | |
gulp.parallel('set-prod-node-env', 'fonts', 'favicons', 'imagemin', 'criticalcss', 'js', 'css') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment