Skip to content

Instantly share code, notes, and snippets.

@sondr3
Created August 29, 2015 18:53
Show Gist options
  • Save sondr3/d5208fc8e7bb77b709b5 to your computer and use it in GitHub Desktop.
Save sondr3/d5208fc8e7bb77b709b5 to your computer and use it in GitHub Desktop.
'use strict';
import gulp from 'gulp';
// Loads the plugins without having to list all of them, but you need
// to call them as $.pluginname
import gulpLoadPlugins from 'gulp-load-plugins';
const $ = gulpLoadPlugins();
// Delete stuff
import del from 'del';
// Used to run shell commands
import shell from 'shelljs';
// BrowserSync is used to live-reload your website
import browserSync from 'browser-sync';
const reload = browserSync.reload;
// Wiredep is used to automatically wire up your Bower dependencies and
// main-bower-files is used to move the files to the 'assets/vendor folder
import wiredeps from 'wiredep';
const wiredep = wiredeps.stream;
import bowerFiles from 'main-bower-files';
// AutoPrefixer
import autoprefixer from 'autoprefixer-core';
/*
* ORGANIZATION OF GULPFILE:
*
* 1. Cleaning assets etc
* 2. Jekyll related tasks
* 3. Development tasks
* 4. Production tasks
* 5 .Deployment tasks
* 6. Various
* 7. Main tasks
*
*/
// 1. Cleaning tasks
gulp.task('clean:dist', del.bind(null, ['dist']));
gulp.task('clean:assets', del.bind(null, ['.tmp', 'dist/assets']));
gulp.task('clean:metadata', del.bind(null, ['src/.jekyll-metadata'], {dot: true}));
// 2. Jekyll tasks
// Build Jekyll without production settings
gulp.task('jekyll:dev', done => {
shell.exec('jekyll build --quiet');
done();
});
// Build Jekyll with production settings
gulp.task('jekyll:prod', done => {
shell.exec('jekyll build --quiet --config _config.yml,_config.build.yml');
done();
});
// Check Jekyll for configuration errors
gulp.task('jekyll:doctor', done => { shell.exec('jekyll doctor'); done(); });
// 3. Development tasks
// Dev task for styles so they can be automatically injected into the browser
gulp.task('styles:dev', () =>
// Don't use partials for best performance
gulp.src('src/assets/scss/style.scss')
// Initiate sourcemaps
.pipe($.sourcemaps.init())
// Run it through libsass
.pipe($.sass({
precision: 10
}).on('error', $.sass.logError))
// Autoprefix things automagically
.pipe($.postcss([
autoprefixer({browsers: 'last 1 version'})
]))
// Write the sourcemaps inline
.pipe($.sourcemaps.write())
// Display the size of the files
.pipe($.size({
title: 'styles',
showFiles: true
}))
// Write it to the temporary directory
.pipe(gulp.dest('.tmp/assets/stylesheets'))
// Inject it directly into the browser
.pipe(browserSync.stream())
);
// Dev task for scrips so they can be automatically injected into the browser
gulp.task('javascript:dev', () =>
// NOTE: The order here is important since it's concatenated in order from
// top to bottom, so you want vendor scripts etc on top
gulp.src([
'src/assets/javascript/vendor.js',
'src/assets/javascript/main.js'
])
// Initiate sourcemaps
.pipe($.sourcemaps.init())
// Concat all the JS files into a single file
.pipe($.concat('index.js'))
// Write the sourcemaps inline
.pipe($.sourcemaps.write())
// Display the size of the files
.pipe($.size({
title: 'scripts',
showFiles: true
}))
// Write it to the temporary directory
.pipe(gulp.dest('.tmp/assets/javascript'))
// Inject it directly into the browser
.pipe(browserSync.stream())
);
// Dev task for injecting the CSS into the HTML
gulp.task('inject:head:dev', () =>
// Change the include file instead of all the HTML files
gulp.src('dist/**/*.html')
// Look for any CSS files in the 'stylesheets' directory
// Don't read the files for performance and ignore the base directory
.pipe($.inject(gulp.src('.tmp/assets/stylesheets/*.css',
{read: false}), {ignorePath: '.tmp'}))
// Output the file back into it's directory
.pipe(gulp.dest('dist'))
);
// Dev task for injecting the JS into the HTML
gulp.task('inject:footer:dev', () =>
// Change the default layout file instead of all the HTML files
gulp.src('dist/**/*.html')
// Look for any JS files in the 'javascript' directory
// Don't read the files for performance and ignore the base directory
.pipe($.inject(gulp.src('.tmp/assets/javascript/*.js',
{read: false}), {ignorePath: '.tmp'}))
// Output the file back into it's directory
.pipe(gulp.dest('dist'))
);
// 4. Production tasks
// Production task for styles
gulp.task('styles', () =>
// Don't include partials for performance
gulp.src('src/assets/scss/style.scss')
// Initiate sourcemaps
.pipe($.sourcemaps.init())
// Run it through libsass
.pipe($.sass({
precision: 10
}).on('error', $.sass.logError))
// Autoprefix things automagically
.pipe($.postcss([
autoprefixer({browsers: 'last 1 version'})
]))
// Rename to show it's minified
.pipe($.rename('style.min.css'))
// Minfiy the CSSS
.pipe($.if('*.css', $.minifyCss()))
// Display the size of the minified CSS
.pipe($.size({
title: 'minified styles',
showFiles: true
}))
// Cache bust the files
.pipe($.rev())
// Write to asset folder
.pipe(gulp.dest('dist/assets/stylesheets'))
// Write the sourcemap into it's own file
.pipe($.sourcemaps.write('.'))
// Write even more to the asset folder
.pipe(gulp.dest('dist/assets/stylesheets'))
// Gzip the CSS file and append .gz
.pipe($.if('*.css', $.gzip({append: true})))
// Display the size of the gzipped file
.pipe($.size({
title: 'gzipped styles',
gzip: true,
showFiles: true
}))
// And put that too into the asset directory
.pipe(gulp.dest('dist/assets/stylesheets'))
);
// Production task for JavaScript
gulp.task('javascript', () =>
// NOTE: The order your list the files in here are important, put vendor
// files etc at the top
gulp.src([
'src/assets/javascript/vendor.js',
'src/assets/javascript/main.js'
])
// Initiate sourcemaps
.pipe($.sourcemaps.init())
// Concat all the JS files into a single file
.pipe($.concat('index.js'))
// Rename to show it's minified
.pipe($.rename('index.min.js'))
// Minify the JS files
.pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
// Cache bust the files
.pipe($.rev())
// Write the sourcemap into it's own file
.pipe($.sourcemaps.write('.'))
// Display the size of the minified JS
.pipe($.size({
title: 'optimized scripts',
showFiles: true
}))
// Write to asset folder
.pipe(gulp.dest('dist/assets/javascript'))
// Gzip the JS file and append .gz
.pipe($.if('*.js', $.gzip({append: true})))
// Display the size of the gzipped file
.pipe($.size({
title: 'gzipped script',
gzip: true,
showFiles: true
}))
// And put that too into the asset directory
.pipe(gulp.dest('dist/assets/javascript'))
);
// Production task for HTML
gulp.task('html', () =>
// We're going to minify all the HTML
gulp.src('dist/**/*.html')
// Through HTMLmin
.pipe($.htmlmin({
// Removing comments
removeComments: true,
// Removing white space
collapseWhitespace: true,
// And other minor optimizations
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true
}))
// Display the size of the minified HTML
.pipe($.size({title: 'optimized HTML'}))
// Output the minified HTML before gzipping it
.pipe(gulp.dest('dist'))
// Gzip all the HTML files and append .gz
.pipe($.gzip({append: true}))
// Display the size of the gzipped file
.pipe($.size({
title: 'gzipped script',
gzip: true
}))
// Write them back to the 'dist' folder
.pipe(gulp.dest('dist'))
);
// Production task for injecting CSS into the HTML
gulp.task('inject:head', () =>
// Change the include file instead of all the HTML files
gulp.src('dist/**/*.html')
// Look for any CSS files in the 'stylesheets' directory
// Don't read the files for performance and ignore the base directory
.pipe($.inject(gulp.src('dist/assets/stylesheets/*.css',
{read: false}), {ignorePath: 'dist'}))
// Output the file back into it's directory
.pipe(gulp.dest('dist'))
);
// Production task for injecting the JS into the HTML
gulp.task('inject:footer', () =>
// Change the default layout file instead of all the HTML files
gulp.src('dist/**/*.html')
// Look for any JS files in the 'javascript' directory
// Don't read the files for performance and ignore the base directory
.pipe($.inject(gulp.src('dist/assets/javascript/*.js',
{read: false}), {ignorePath: 'dist'}))
// Output the file back into it's directory
.pipe(gulp.dest('dist'))
);
// Production (and dev) task for images
gulp.task('images', () =>
// Look for any kind of file in the images folder and subfolders
// I hope you only put images here...
gulp.src('src/assets/images/**/*')
// Cache them so you don't repeatedly optimize them
.pipe($.cache($.imagemin({
// Progressively enhance JPEGs
progressive: true,
// Interlace PNGs
interlaced: true
})))
// Output to both temporary and dist folders
.pipe(gulp.dest('.tmp/assets/images'))
.pipe(gulp.dest('dist/assets/images'))
// And display the size of the images
.pipe($.size({title: 'images'}))
);
// Production (and dev) task for fonts
gulp.task('fonts', () =>
// Look for any kind of file in the fonts folder and subfolders
// You get the drift
gulp.src('src/assets/fonts/**/*')
// Copy them to the temporary and dist folder
.pipe(gulp.dest('.tmp/assets/images'))
.pipe(gulp.dest('dist/assets/fonts'))
// And display the size
.pipe($.size({title: 'fonts'}))
);
// Wires your Bower dependencies into their own include file that are then
// inserted into the default layout, automatically adding JS and CSS
gulp.task('bower', () => {
// Bower dependencies to exlude, for example:
// const bowerExcludes = ['jquery'];
const bowerExcludes = [];
return gulp.src('src/_includes/bower_{scripts,styles}.html')
.pipe(wiredep({
exclude: bowerExcludes,
fileTypes: {
html: {
replace: {
js: filePath => {
return '<script src="' + '/assets/vendor/' + filePath.split('/').pop() + '"></script>';
},
css: filePath => {
return '<link rel="stylesheet" href="' + '/assets/vendor/' + filePath.split('/').pop() + '"/>';
}
}
}
}
}))
.pipe(gulp.dest('src/_includes'));
});
// Copies the Bower dependencies into the '.tmp' folder so they work with
// BrowserSync
gulp.task('bower:files', () => {
return gulp.src(bowerFiles())
.pipe(gulp.dest('.tmp/assets/vendor'))
.pipe($.size({title: 'Bower assets for development'}));
});
// Task to upload your site via Rsync to your server
gulp.task('deploy', () => {
// Load in the variables needed for our Rsync synchronization
var secret = require('./rsync-credentials.json');
return gulp.src('dist/**')
.pipe($.rsync({
// This uploads the contenst of 'root', instead of the folder
root: 'dist',
// Find your username, hostname and destination from your rsync-credentials.json
hostname: secret.hostname,
username: secret.username,
destination: secret.destination,
// Incremental uploading, adds a small delay but minimizes the amount of files transferred
incremental: true,
// Shows the progress on your files while uploading
progress: true
}));
});
gulp.task('lint', () =>
gulp.src([
'gulpfile.babel.js',
'.tmp/assets/javascript/*.js'
])
.pipe($.eslint())
.pipe($.eslint.formatEach())
.pipe($.eslint.failOnError())
);
// BrowserSync will serve our site on a local server for us and other devices to use
// It will also autoreload across all devices as well as keep the viewport synchronized
// between them.
gulp.task('serve', () => {
browserSync({
// tunnel: true,
open: false,
server: {
baseDir: ['.tmp', 'dist']
}
});
// Watch various files for changes and do the needful
gulp.watch(['src/**/*.md', 'src/**/*.html', 'src/**/*.xml',
'src/**/*.txt', 'src/**/*.yml']), gulp.series('jekyll:dev', reload);
gulp.watch('src/assets/javascript/**/*.js', gulp.series('javascript:dev'));
gulp.watch('src/assets/scss/**/*.scss', gulp.series('styles:dev'));
gulp.watch('src/assets/images/**/*', reload);
});
gulp.task('serve:dist', () => {
browserSync({
notify: true,
server: {
baseDir: ['dist']
}
});
});
gulp.task('assets:dev', gulp.series('styles:dev', 'javascript:dev', 'fonts', 'images'));
gulp.task('assets', gulp.series('styles', 'javascript', 'fonts', 'images'));
// Default task, run when just writing 'gulp' in the terminal
gulp.task('default', gulp.series(
gulp.series('jekyll:dev'),
gulp.series('assets:dev', 'inject:head:dev', 'inject:footer:dev'),
gulp.series('serve')
));
gulp.task('build', gulp.series(
gulp.series('jekyll:prod'),
gulp.series('assets', 'inject:head', 'inject:footer'),
gulp.series('html')
));
// Clean out your dist and .tmp folder and delete .jekyll-metadata
gulp.task('rebuild', gulp.series('clean:dist', 'clean:assets', 'clean:metadata'));
// Checks your CSS, JS and Jekyll for errors
gulp.task('check', gulp.series('jekyll:doctor', 'lint'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment