Skip to content

Instantly share code, notes, and snippets.

@waako
Created February 20, 2017 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waako/e0904e215bda1d4bb848d2091a7d3215 to your computer and use it in GitHub Desktop.
Save waako/e0904e215bda1d4bb848d2091a7d3215 to your computer and use it in GitHub Desktop.
Gulpfile.js v4
var gulp = require('gulp'),
fs = require('fs'),
path = require('path'),
naturalSort = require('gulp-natural-sort'),
browserSync = require('browser-sync'),
cp = require('child_process'),
rsync = require('gulp-rsync'),
rev = require('gulp-rev'),
del = require('del'),
collect = require('gulp-rev-collector'),
// Compression
zopfli = require("gulp-zopfli"),
compressSettings = {
verbose: false,
verbose_more: false,
numiterations: 15,
blocksplitting: true,
blocksplittinglast: false,
blocksplittingmax: 15
},
// CSS
sass = require('gulp-sass'),
prefix = require('gulp-autoprefixer'),
cssnano = require('gulp-cssnano'),
uncss = require('gulp-uncss'),
stripCssComments = require('gulp-strip-css-comments'),
gulpMinifyCssNames = require('gulp-minify-cssnames'),
critical = require('critical').stream,
inlinesource = require('gulp-inline-source'),
// JS
uglify = require('gulp-uglify'),
pump = require('pump'),
// HTML
htmlmin = require('gulp-htmlmin'),
// JSON
jsonminify = require('gulp-jsonminify'),
// Images
responsive = require('gulp-responsive'),
directoryMap = require("gulp-directory-map"),
imagemin = require('gulp-imagemin'),
// Jekyll
jekyll = process.platform === 'win32' ? 'jekyll.bat' : 'jekyll',
messages = {
jekyllBuild: '<span style="color: grey">Running:</span> $ jekyll build'
};
/* ======================== Shared tasks ======================== */
/**
* Clean destination folder _site
*/
gulp.task('clean', function() {
return del('_site/');
});
/* ======================== Development ======================== */
/**
* Build the Jekyll Site for development
*/
gulp.task('build', function(done) {
browserSync.notify(messages.jekyllBuild);
cp.exec('bundle exec jekyll build').on('close', done);
});
/**
* Rebuild Jekyll & do page reload
*/
gulp.task('rebuild', gulp.series('build', function(done) {
browserSync.reload();
}));
/**
* Compile files from _scss into both _site/css (for live injecting) and site (for future jekyll builds)
*/
gulp.task('sass', function() {
return gulp.src(['_sass/base.scss', '_sass/style.scss', '_sass/cv.scss'])
.pipe(sass({
includePaths: ['scss'],
onError: browserSync.notify
}))
.pipe(gulp.dest('_site/css'))
.pipe(browserSync.reload({
stream: true
}));
});
/**
* Inline base CSS, above the fold
*/
gulp.task('inline-critical', function () {
var options = {
compress: false
};
return gulp.src('_site/**/*.html')
.pipe(inlinesource(options))
.pipe(gulp.dest('_site'));
});
/**
* Compile JavaScript from _js into the _site
*/
gulp.task('js', function() {
return gulp.src('_js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('_site/js'))
.pipe(browserSync.reload({
stream: true
}));
});
/**
* Wait for jekyll-build, then launch the Server
*/
gulp.task('browser-sync', function(cb) {
browserSync({
server: {
baseDir: '_site'
},
port: 3000,
notify: true,
open: true
}, cb);
});
/**
* Watch scss files for changes & recompile
* Watch html/md files, run jekyll & reload BrowserSync
*/
gulp.task('watch:markup', function() {
gulp.watch([
'*.html',
'*.md',
'_includes/*.html',
'_layouts/*.html',
'_posts/*',
'_works/*'
],gulp.series('build', gulp.parallel('sass', 'js')), function(){
browserSync.reload();
});
});
gulp.task('watch:styles', function() {
gulp.watch('_sass/**/*.scss', gulp.parallel('sass'));
});
gulp.task('watch:scripts', function() {
gulp.watch('_js/*.js', gulp.parallel('js'));
});
gulp.task('watch', gulp.parallel(
'watch:markup',
'watch:styles',
'watch:scripts'
));
/**
* Default task, running just `gulp` will compile the sass,
* compile the jekyll site, launch BrowserSync & watch files.
*/
gulp.task('default', gulp.series('clean', 'build', gulp.parallel('sass', 'js', 'browser-sync', 'watch')));
/* ======================== Deployment ======================== */
/**
* Build SASS for production
*/
gulp.task('sass:prod', function () {
return gulp.src(['_sass/base.scss', '_sass/style.scss', '_sass/cv.scss'])
.pipe(sass({
includePaths: ['scss']
}))
.pipe(prefix(['last 15 versions', '> 1%', 'ie 8', 'ie 7'], {
cascade: true
}))
.pipe(uncss({
html: ['_site/**/*.html']
}))
.pipe(cssnano())
.pipe(stripCssComments())
.pipe(rev())
.pipe(gulp.dest('_site/css'))
.pipe(rev.manifest())
.pipe(gulp.dest('_site/css'));
});
/**
* Inline base CSS, above the fold
*/
gulp.task('inline-critical:prod', function () {
var options = {
compress: true
};
return gulp.src('_site/**/*.html')
.pipe(inlinesource(options))
.pipe(gulp.dest('_site'));
});
/**
* TESTING: Generate critical CSS, above the fold
*/
gulp.task('critical-css:prod', function () {
// Get revisioned CSS file
var json = JSON.parse(fs.readFileSync('_site/css/rev-manifest.json'));
return gulp.src('_site/**/*.html')
.pipe(critical({
base: '_site/',
inline: true,
minify: true,
extract: true,
css: '_site/css/' + json['style.css']
}))
.pipe(gulp.dest('_site'));
});
/**
* Compile JavaScript from _js into the _site
*/
gulp.task('js:prod', function() {
return gulp.src('_js/**/*.js')
.pipe(uglify())
.pipe(rev())
.pipe(gulp.dest('_site/js'))
.pipe(rev.manifest())
.pipe(gulp.dest('_site/js'));
});
/**
* Compress JSON files
*/
gulp.task('compress-json:prod', function() {
return gulp.src('_site/posts.json')
.pipe(jsonminify())
.pipe(gulp.dest('_site'));
});
/**
* Revisioning files update
*/
gulp.task('rev:prod', function() {
return gulp.src(['_site/**/*.json', '_site/**/*.html'])
.pipe(collect({
replaceReved: true
}))
.pipe(gulp.dest('_site'));
});
/**
* Gzip CSS files
*/
gulp.task('gzip-css:prod', function() {
return gulp.src('_site/css/*.css')
.pipe(zopfli(compressSettings))
.pipe(gulp.dest('_site/css'));
});
/**
* Gzip JS files
*/
gulp.task('gzip-js:prod', function() {
return gulp.src('_site/js/*.js')
.pipe(zopfli(compressSettings))
.pipe(gulp.dest('_site/js'));
});
/**
* Gzip XML and JSON
*/
gulp.task('gzip-other:prod', function(done) {
return gulp.src(['_site/*.xml','_site/*.json'])
.pipe(zopfli(compressSettings))
.pipe(gulp.dest('_site'));
});
/**
* Min HTML
*/
gulp.task('min-html:prod', function() {
return gulp.src(['_site/**/*.html'])
.pipe(htmlmin({
removeComments: true,
collapseWhitespace: true,
minifyJS: true
}))
.pipe(gulp.dest('_site'))
.pipe(zopfli(compressSettings))
.pipe(gulp.dest('_site'));
});
/**
* Min posts HTML
*/
gulp.task('min-posts-html:prod', function() {
return gulp.src([
'_site/*/*/*/*/*.html'
])
.pipe(htmlmin({
removeComments: true,
collapseWhitespace: true,
minifyJS: true
}))
.pipe(gulp.dest('_site'))
.pipe(zopfli(compressSettings))
.pipe(gulp.dest('_site'));
});
gulp.task('prod', gulp.series(
'clean',
'build',
'sass:prod',
'js:prod',
'rev:prod',
'inline-critical:prod',
gulp.parallel(
'min-html:prod',
'min-posts-html:prod',
'compress-json:prod',
'gzip-css:prod',
'gzip-js:prod',
'gzip-other:prod'
)
));
/* ======================== Images gen ======================== */
/**
* Create responsive images
*/
gulp.task('images-gen', function () {
return gulp.src('_images/review-sennheiser-momentum-over-ear-headphones/**/*.{png,jpg,JPG,jpeg}')
.pipe(responsive({
'**/**/*.{png,jpg,JPG,jpeg}': [
// Preview photo
{
width: 42,
blur: true,
rename: {
suffix: '-preview',
extname: '.jpg',
},
format: 'jpeg'
/* Small photo */
},{
width: 480,
rename: {
suffix: '-480px',
extname: '.webp',
},
format: 'webp'
},{
width: 480,
rename: {
suffix: '-480px',
extname: '.jpg',
},
format: 'jpeg'
// Medium photo
},{
width: 960,
rename: {
suffix: '-960px',
extname: '.webp',
},
format: 'webp'
},{
width: 960,
rename: {
suffix: '-960px',
extname: '.jpg',
},
format: 'jpeg'
// Large photo
},{
width: 1920,
rename: {
suffix: '-1920px',
extname: '.webp',
},
format: 'webp'
},{
width: 1920,
rename: {
suffix: '-1920px',
extname: '.jpg',
},
format: 'jpeg'
}]
}, {
quality: 75,
progressive: true,
withMetadata: false,
withoutEnlargement: false,
rotate: true
}))
.pipe(gulp.dest('images/optimized'));
});
/**
* Create JSON file with all gallery images for each gallery
*/
// Get all gallery folders
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
// Map each folder with gallery
gulp.task('images-map', function(){
var folders = getFolders('_images');
return folders.map(function(folder) {
if (fs.existsSync('_images/'+ folder +'/gallery')){
return gulp.src('_images/'+ folder +'/gallery/*.{png,jpg,JPG}')
.pipe(naturalSort())
.pipe(directoryMap({
filename: 'images.json'
}))
.pipe(gulp.dest('images/optimized/' + folder));
}
});
});
/**
* Minify PNG, JPEG, GIF and SVG images
gulp.task('image-min', () =>
gulp.src('src/images/')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'))
);*/
gulp.task('images', gulp.series('images-gen', 'images-map'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment