From 34cbacdd56f680fd59414d0f03e3e6a8f13b014d Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 20:44:13 +0100 Subject: [PATCH 1/7] ES6 gulp --- .babelrc | 3 ++ gulpfile.js => gulpfile.babel.js | 78 ++++++++++++++++---------------- package.json | 2 + 3 files changed, 44 insertions(+), 39 deletions(-) create mode 100644 .babelrc rename gulpfile.js => gulpfile.babel.js (88%) diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..af0f0c3d --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.babel.js similarity index 88% rename from gulpfile.js rename to gulpfile.babel.js index 8ba76cbd..e152d985 100644 --- a/gulpfile.js +++ b/gulpfile.babel.js @@ -1,23 +1,23 @@ 'use strict' // load plugins -var $ = require('gulp-load-plugins')() +const $ = require('gulp-load-plugins')() // manually require modules that won"t get picked up by gulp-load-plugins -var gulp = require('gulp'), - del = require('del'), - pkg = require('./package.json'), - parallelize = require('concurrent-transform'), - browser = require('browser-sync'), - autoprefixer = require('autoprefixer'), - cssnano = require('cssnano') +const gulp = require('gulp'), + del = require('del'), + pkg = require('./package.json'), + parallelize = require('concurrent-transform'), + browser = require('browser-sync'), + autoprefixer = require('autoprefixer'), + cssnano = require('cssnano') // Temporary solution until gulp 4 // https://github.com/gulpjs/gulp/issues/355 -var runSequence = require('run-sequence') +const runSequence = require('run-sequence') // handle errors -var onError = function(error) { +const onError = (error) => { $.util.log('') $.util.log($.util.colors.red('You fucked up:', error.message, 'on line' , error.lineNumber)) $.util.log('') @@ -26,7 +26,7 @@ var onError = function(error) { // 'development' is just default, production overrides are triggered // by adding the production flag to the gulp command e.g. `gulp build --production` -var isProduction = ($.util.env.production === true ? true : false) +const isProduction = ($.util.env.production === true ? true : false) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Terminal Banner @@ -45,20 +45,20 @@ console.log("") // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Port to use for the development server. -var PORT = 1337 +const PORT = 1337 // Browsers to target when prefixing CSS. -var COMPATIBILITY = ['last 2 versions', 'ie >= 10'] +const COMPATIBILITY = ['last 2 versions', 'ie >= 10'] // paths -var SRC = '_src', - DIST = '_site', - S3BUCKET = 'kremalicious.com', - S3PATH = '/', - S3REGION = 'eu-central-1' +const SRC = '_src', + DIST = '_site', + S3BUCKET = 'kremalicious.com', + S3PATH = '/', + S3REGION = 'eu-central-1' // icons -var ICONS = { +const ICONS = { entypo: { src: SRC + '/_assets/icons/entypo/', dist: DIST + '/assets/img/', @@ -69,7 +69,7 @@ var ICONS = { } } -var iconset = ICONS.entypo +const iconset = ICONS.entypo // Iterate through the icon set array iconset.icons.forEach(function(icon, i, icons) { @@ -77,7 +77,7 @@ iconset.icons.forEach(function(icon, i, icons) { }) // SVG sprite -var SPRITE = { +const SPRITE = { dest: DIST + '/assets/img/', mode: { symbol: { @@ -88,7 +88,7 @@ var SPRITE = { } // code banner -var BANNER = [ +const BANNER = [ '/**', ' ** <%= pkg.name %> v<%= pkg.version %>', ' ** <%= pkg.description %>', @@ -116,7 +116,7 @@ var BANNER = [ // // Delete build artifacts // -gulp.task('clean', function(done) { +gulp.task('clean', (done) => { return del([ DIST + '/**/*', DIST + '/.*', // delete all hidden files @@ -128,7 +128,7 @@ gulp.task('clean', function(done) { // // Jekyll // -gulp.task('jekyll', function(cb) { +gulp.task('jekyll', (cb) => { browser.notify('Compiling Jekyll') var spawn = require('child_process').spawn @@ -149,7 +149,7 @@ gulp.task('jekyll', function(cb) { // // HTML // -gulp.task('html', function() { +gulp.task('html', () => { return gulp.src(DIST + '/**/*.html') .pipe($.if(isProduction, $.htmlmin({ collapseWhitespace: true, @@ -169,7 +169,7 @@ gulp.task('html', function() { // // Styles // -gulp.task('css', function() { +gulp.task('css', () => { var processors = [ autoprefixer({ browsers: COMPATIBILITY }), @@ -196,7 +196,7 @@ gulp.task('css', function() { // // Libraries -gulp.task('js:libraries', function() { +gulp.task('js:libraries', () => { return gulp.src([ 'node_modules/picturefill/dist/picturefill.js' ]) @@ -206,7 +206,7 @@ gulp.task('js:libraries', function() { }) // Project js -gulp.task('js:project', function() { +gulp.task('js:project', () => { return gulp.src(SRC + '/_assets/js/kremalicious3.js') .pipe($.sourcemaps.init()) .pipe($.include()).on('error', onError) @@ -218,7 +218,7 @@ gulp.task('js:project', function() { }) // Service Worker js -gulp.task('js:sw', function() { +gulp.task('js:sw', () => { return gulp.src(DIST + '/service-worker.js') .pipe($.if(isProduction, $.uglify({ compress: { @@ -235,7 +235,7 @@ gulp.task('js', ['js:libraries', 'js:project', 'js:sw']) // // Icons // -gulp.task('icons', function() { +gulp.task('icons', () => { return gulp.src(iconset.icons) .pipe($.rename({ prefix: iconset.prefix })) .pipe(gulp.dest(iconset.dist)) @@ -249,7 +249,7 @@ gulp.task('icons', function() { // // Copy images // -gulp.task('images', function() { +gulp.task('images', () => { return gulp.src([ SRC + '/_assets/img/**/*', '!' + SRC + '/_assets/img/entypo/**/*' @@ -268,7 +268,7 @@ gulp.task('images', function() { // // Copy fonts // -gulp.task('fonts', function() { +gulp.task('fonts', () => { return gulp.src(SRC + '/_assets/fonts/**/*') .pipe(gulp.dest(DIST + '/assets/fonts/')) }) @@ -277,7 +277,7 @@ gulp.task('fonts', function() { // // Copy media // -gulp.task('media', function() { +gulp.task('media', () => { return gulp.src(SRC + '/_media/**/*') .pipe(gulp.dest(DIST + '/media/')) }) @@ -286,7 +286,7 @@ gulp.task('media', function() { // // Revision static assets // -gulp.task('rev', function() { +gulp.task('rev', () => { // globbing is slow so do everything conditionally for faster dev build if (isProduction) { return gulp.src(DIST + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff}') @@ -303,7 +303,7 @@ gulp.task('rev', function() { // Replace all links to assets in files // from a manifest file // -gulp.task('rev:replace', function() { +gulp.task('rev:replace', () => { // globbing is slow so do everything conditionally for faster dev build if (isProduction) { var manifest = gulp.src(DIST + '/assets/rev-manifest.json') @@ -317,7 +317,7 @@ gulp.task('rev:replace', function() { // // Dev Server // -gulp.task('server', ['build'], function() { +gulp.task('server', ['build'], () => { browser.init({ server: DIST, port: PORT, @@ -334,7 +334,7 @@ gulp.task('server', ['build'], function() { // // Build site, run server, and watch for file changes // -gulp.task('default', ['build', 'server'], function() { +gulp.task('default', ['build', 'server'], () => { gulp.watch([SRC + '/_assets/styl/**/*.styl'], ['css']) gulp.watch([SRC + '/_assets/js/*.js'], ['js', browser.reload]) gulp.watch([SRC + '/_assets/img/**/*.{png,jpg,jpeg,gif}'], ['images', browser.reload]) @@ -347,7 +347,7 @@ gulp.task('default', ['build', 'server'], function() { // // Full build // -gulp.task('build', function(done) { +gulp.task('build', (done) => { console.log($.util.colors.gray(" ------------------------------------------")) console.log($.util.colors.green(' Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')) @@ -367,7 +367,7 @@ gulp.task('build', function(done) { // // Deploy to S3 // -gulp.task('deploy', function() { +gulp.task('deploy', () => { // create publisher, define config var publisher = $.awspublish.create({ diff --git a/package.json b/package.json index f625ea05..5b7f2169 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ }, "devDependencies": { "autoprefixer": ">=6.3.6", + "babel-core": "^6.24.0", + "babel-preset-es2015": "^6.24.0", "browser-sync": ">=2.10.0", "concurrent-transform": ">=1.0.0", "cssnano": ">=3.6.2", From 43bfda3cc732df809a73228b0a8e6844a9de92f8 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 20:44:51 +0100 Subject: [PATCH 2/7] remove jekyll-archives fix --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 72ec735c..5dd0235b 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ group :jekyll do gem 'jekyll-sitemap' gem 'jekyll-redirect-from' gem 'jekyll-picture-tag' - gem 'jekyll-archives', :git => 'https://github.com/jekyll/jekyll-archives.git' #temporary fix for https://github.com/jekyll/jekyll-archives/issues/75 + gem 'jekyll-archives' gem 'jekyll-paginate' end From 35c40b7d882eb46b7a9870bad1aefbf5ef9cb2c0 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 21:19:54 +0100 Subject: [PATCH 3/7] more ES6 gulp --- gulpfile.babel.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/gulpfile.babel.js b/gulpfile.babel.js index e152d985..6da65040 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -3,18 +3,18 @@ // load plugins const $ = require('gulp-load-plugins')() -// manually require modules that won"t get picked up by gulp-load-plugins -const gulp = require('gulp'), - del = require('del'), - pkg = require('./package.json'), - parallelize = require('concurrent-transform'), - browser = require('browser-sync'), - autoprefixer = require('autoprefixer'), - cssnano = require('cssnano') +// manually import modules that won't get picked up by gulp-load-plugins +import gulp from 'gulp' +import del from 'del' +import pkg from './package.json' +import parallelize from 'concurrent-transform' +import browser from 'browser-sync' +import autoprefixer from 'autoprefixer' +import cssnano from 'cssnano' // Temporary solution until gulp 4 // https://github.com/gulpjs/gulp/issues/355 -const runSequence = require('run-sequence') +import runSequence from 'run-sequence' // handle errors const onError = (error) => { @@ -334,7 +334,7 @@ gulp.task('server', ['build'], () => { // // Build site, run server, and watch for file changes // -gulp.task('default', ['build', 'server'], () => { +gulp.task('default', ['server'], () => { gulp.watch([SRC + '/_assets/styl/**/*.styl'], ['css']) gulp.watch([SRC + '/_assets/js/*.js'], ['js', browser.reload]) gulp.watch([SRC + '/_assets/img/**/*.{png,jpg,jpeg,gif}'], ['images', browser.reload]) @@ -372,11 +372,11 @@ gulp.task('deploy', () => { // create publisher, define config var publisher = $.awspublish.create({ params: { - "Bucket": S3BUCKET + 'Bucket': S3BUCKET }, - "accessKeyId": process.env.AWS_ACCESS_KEY, - "secretAccessKey": process.env.AWS_SECRET_KEY, - "region": S3REGION + 'accessKeyId': process.env.AWS_ACCESS_KEY, + 'secretAccessKey': process.env.AWS_SECRET_KEY, + 'region': S3REGION }) return gulp.src(DIST + '/**/*') From 5e735b1a1ef7eb07d6fb68b993a87a8227642320 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 22:05:01 +0100 Subject: [PATCH 4/7] gulp 4 --- .editorconfig | 13 +++ .travis.yml | 4 +- gulpfile.babel.js | 198 ++++++++++++++++++++++++++-------------------- package.json | 5 +- 4 files changed, 130 insertions(+), 90 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b64e0cd9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ + +# EditorConfig is awesome: http://EditorConfig.org + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true + +[*.json] +indent_size = 2 diff --git a/.travis.yml b/.travis.yml index 016ff71e..e0a20d9f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: trusty language: ruby rvm: - - 2.3.0 + - 2.4.0 cache: bundler: true @@ -22,7 +22,7 @@ addons: - libgsl0-dev before_install: - - nvm install 6 + - nvm install 7 before_script: "_ci/setup.sh" script: "_ci/build.sh" diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 6da65040..9bf571e4 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -12,10 +12,6 @@ import browser from 'browser-sync' import autoprefixer from 'autoprefixer' import cssnano from 'cssnano' -// Temporary solution until gulp 4 -// https://github.com/gulpjs/gulp/issues/355 -import runSequence from 'run-sequence' - // handle errors const onError = (error) => { $.util.log('') @@ -110,46 +106,82 @@ const BANNER = [ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// Tasks +// gulp tasks +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// +// Full build +// +// `gulp build` is the development build +// `gulp build --production` is the production build +// +gulp.task('build', gulp.series( + buildBanner, clean, jekyll, + gulp.parallel(html, css, js, images, icons, fonts, media), + rev, revReplace +)) + +function buildBanner(done) { + console.log($.util.colors.gray(" ------------------------------------------")) + console.log($.util.colors.green(' Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')) + console.log($.util.colors.gray(" ------------------------------------------")) + + done() +} + + +// +// Build site, run server, and watch for file changes +// +gulp.task('default', gulp.series('build', server, watch)) + + + +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// Functions // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // // Delete build artifacts // -gulp.task('clean', (done) => { +function clean(done) { return del([ - DIST + '/**/*', - DIST + '/.*', // delete all hidden files + DIST + '**/*', + DIST + '.*', // delete all hidden files '!' + DIST + '/media/**' - ], done) -}) + ]) + + done() +} // // Jekyll // -gulp.task('jekyll', (cb) => { - browser.notify('Compiling Jekyll') +function jekyll(done) { - var spawn = require('child_process').spawn + browser.notify('Compiling Jekyll') if (isProduction) { process.env.JEKYLL_ENV = 'production' - var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--lsi'], { stdio: 'inherit' }) + var jekyll_options = 'jekyll build --lsi' } else { - var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--config', '_config.yml,_config.dev.yml', '--drafts', '--future', '--incremental'], { stdio: 'inherit' }) + var jekyll_options = 'jekyll build --config _config.yml,_config.dev.yml --incremental --drafts --future' } - jekyll.on('exit', function(code) { - cb(code === 0 ? null : 'ERROR: Jekyll process exited with code: ' + code) - }) -}) + var spawn = require('child_process').spawn, + jekyll = spawn('bundle', ['exec', jekyll_options], { stdio: 'inherit' }) + + return jekyll + .on('error', (error) => onError() ) + .on('close', done) +} // // HTML // -gulp.task('html', () => { +function html() { return gulp.src(DIST + '/**/*.html') .pipe($.if(isProduction, $.htmlmin({ collapseWhitespace: true, @@ -163,13 +195,13 @@ gulp.task('html', () => { minifyCSS: true }))) .pipe(gulp.dest(DIST)) -}) +} // // Styles // -gulp.task('css', () => { +function css() { var processors = [ autoprefixer({ browsers: COMPATIBILITY }), @@ -188,7 +220,7 @@ gulp.task('css', () => { .pipe($.rename({ suffix: '.min' })) .pipe(gulp.dest(DIST + '/assets/css/')) .pipe(browser.stream()) -}) +} // @@ -196,17 +228,17 @@ gulp.task('css', () => { // // Libraries -gulp.task('js:libraries', () => { +function jsLibraries() { return gulp.src([ 'node_modules/picturefill/dist/picturefill.js' ]) .pipe($.if(isProduction, $.uglify())).on('error', onError) .pipe($.rename({ suffix: '.min'})) .pipe(gulp.dest(DIST + '/assets/js/')) -}) +} // Project js -gulp.task('js:project', () => { +function jsProject() { return gulp.src(SRC + '/_assets/js/kremalicious3.js') .pipe($.sourcemaps.init()) .pipe($.include()).on('error', onError) @@ -215,10 +247,10 @@ gulp.task('js:project', () => { .pipe($.if(isProduction, $.header(BANNER, { pkg: pkg }))) .pipe($.rename({suffix: '.min'})) .pipe(gulp.dest(DIST + '/assets/js/')) -}) +} // Service Worker js -gulp.task('js:sw', () => { +function jsSW() { return gulp.src(DIST + '/service-worker.js') .pipe($.if(isProduction, $.uglify({ compress: { @@ -226,16 +258,18 @@ gulp.task('js:sw', () => { } }))).on('error', onError) .pipe(gulp.dest(DIST + '/')) -}) +} // Collect all script tasks -gulp.task('js', ['js:libraries', 'js:project', 'js:sw']) +function js() { + return jsLibraries(), jsProject(), jsSW() +} // // Icons // -gulp.task('icons', () => { +function icons() { return gulp.src(iconset.icons) .pipe($.rename({ prefix: iconset.prefix })) .pipe(gulp.dest(iconset.dist)) @@ -243,13 +277,13 @@ gulp.task('icons', () => { .pipe($.if(isProduction, $.imagemin({ svgoPlugins: [{ removeViewBox: false }] }))) .pipe($.svgSprite(SPRITE)) .pipe(gulp.dest(iconset.dist)) -}) +} // // Copy images // -gulp.task('images', () => { +function images() { return gulp.src([ SRC + '/_assets/img/**/*', '!' + SRC + '/_assets/img/entypo/**/*' @@ -262,48 +296,49 @@ gulp.task('images', () => { svgoPlugins: [{ removeViewBox: false }] }))) .pipe(gulp.dest(DIST + '/assets/img/')) -}) +} // // Copy fonts // -gulp.task('fonts', () => { +function fonts() { return gulp.src(SRC + '/_assets/fonts/**/*') .pipe(gulp.dest(DIST + '/assets/fonts/')) -}) +} // // Copy media // -gulp.task('media', () => { +function media() { return gulp.src(SRC + '/_media/**/*') .pipe(gulp.dest(DIST + '/media/')) -}) +} // // Revision static assets // -gulp.task('rev', () => { +function rev(done) { // globbing is slow so do everything conditionally for faster dev build if (isProduction) { - return gulp.src(DIST + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff}') + return gulp.src(DIST + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff,woff2}') .pipe($.if(isProduction, $.rev())) .pipe(gulp.dest(DIST + '/assets/')) // output rev manifest for next replace task .pipe($.if(isProduction, $.rev.manifest())) .pipe(gulp.dest(DIST + '/assets/')) } -}) + done() +} // // Replace all links to assets in files // from a manifest file // -gulp.task('rev:replace', () => { +function revReplace(done) { // globbing is slow so do everything conditionally for faster dev build if (isProduction) { var manifest = gulp.src(DIST + '/assets/rev-manifest.json') @@ -311,63 +346,42 @@ gulp.task('rev:replace', () => { .pipe($.if(isProduction, $.revReplace({ manifest: manifest }))) .pipe(gulp.dest(DIST)) } -}) + done() +} // // Dev Server // -gulp.task('server', ['build'], () => { +function server(done) { browser.init({ server: DIST, port: PORT, reloadDebounce: 2000 }) -}) + + done() +} + + +// +// Watch for file changes +// +function watch() { + gulp.watch(SRC + '_assets/styl/**/*.styl').on('all', gulp.series(css)) + gulp.watch(SRC + '_assets/js/**/*.js').on('all', gulp.series(js, browser.reload)) + gulp.watch(SRC + '_assets/img/**/*.{png,jpg,jpeg,gif,webp}').on('all', gulp.series(images, browser.reload)) + gulp.watch(SRC + '_assets/img/**/*.{svg}').on('all', gulp.series(icons, browser.reload)) + gulp.watch(SRC + '_media/**/*').on('all', gulp.series(media, browser.reload)) + gulp.watch([SRC + '/**/*.{html,xml,json,txt,md,yml}', './*.yml', SRC + '_includes/svg/*']).on('all', gulp.series('build', browser.reload)) +} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// Task sequences +// Deployment // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -// -// Build site, run server, and watch for file changes -// -gulp.task('default', ['server'], () => { - gulp.watch([SRC + '/_assets/styl/**/*.styl'], ['css']) - gulp.watch([SRC + '/_assets/js/*.js'], ['js', browser.reload]) - gulp.watch([SRC + '/_assets/img/**/*.{png,jpg,jpeg,gif}'], ['images', browser.reload]) - gulp.watch([SRC + '/_assets/img/**/*.{svg}'], ['icons', browser.reload]) - gulp.watch([SRC + '/_media/**/*'], ['media', browser.reload]) - gulp.watch([SRC + '/**/*.{html,xml,json,txt,md,yml}', './*.yml'], ['build', browser.reload]) -}) - - -// -// Full build -// -gulp.task('build', (done) => { - - console.log($.util.colors.gray(" ------------------------------------------")) - console.log($.util.colors.green(' Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')) - console.log($.util.colors.gray(" ------------------------------------------")) - - runSequence( - 'clean', - 'jekyll', - ['html', 'css', 'js', 'images', 'icons', 'fonts', 'media'], - 'rev', - 'rev:replace', - done - ) -}) - - -// -// Deploy to S3 -// -gulp.task('deploy', () => { +gulp.task('deploy', (done) => { // create publisher, define config var publisher = $.awspublish.create({ @@ -387,7 +401,7 @@ gulp.task('deploy', () => { }, routes: { // all static assets, cached & gzipped - '^assets/(?:.+)\\.(?:js|css|png|jpg|jpeg|gif|ico|svg|ttf)$': { + '^assets/(?:.+)\\.(?:js|css|png|jpg|jpeg|gif|ico|svg|ttf|eot|woff|woff2)$': { cacheTime: 2592000, // cache for 1 month gzip: true }, @@ -403,6 +417,20 @@ gulp.task('deploy', () => { gzip: true }, + // font mime types + '\.ttf$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-ttf' } + }, + '\.woff$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-woff' } + }, + '\.woff2$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-woff2' } + }, + // pass-through for anything that wasn't matched by routes above, to be uploaded with default options "^.+$": "$&" } diff --git a/package.json b/package.json index 5b7f2169..e57baeae 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "concurrent-transform": ">=1.0.0", "cssnano": ">=3.6.2", "del": ">=1.2.0", - "gulp": ">=3.8.0", + "gulp": "github:gulpjs/gulp#4.0", "gulp-awspublish": ">=2.0.2", "gulp-awspublish-router": ">=0.1.1", "gulp-filter": ">=2.0.2", @@ -51,8 +51,7 @@ "gulp-stylus": ">=2.3.1", "gulp-svg-sprite": ">=1.2.2", "gulp-uglify": ">=1.2.0", - "gulp-util": ">=3.0.6", - "run-sequence": ">=1.1.0" + "gulp-util": ">=3.0.6" }, "engines": { "node": ">=5.0.0" From cbbfc80b387f846375f3653d92d468f47e50cb40 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 22:22:06 +0100 Subject: [PATCH 5/7] add gulp-cli as dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index e57baeae..b64e5bff 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "gulp": "github:gulpjs/gulp#4.0", "gulp-awspublish": ">=2.0.2", "gulp-awspublish-router": ">=0.1.1", + "gulp-cli": ">=1.2.2", "gulp-filter": ">=2.0.2", "gulp-header": ">=1.2.2", "gulp-htmlmin": ">=1.1.2", From fdb26ceba9c6538ee5e5e4b622af41d4ab930cf3 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 22:27:24 +0100 Subject: [PATCH 6/7] fix build --- _ci/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ci/setup.sh b/_ci/setup.sh index 68d423bf..4f979053 100755 --- a/_ci/setup.sh +++ b/_ci/setup.sh @@ -7,7 +7,7 @@ echo " Installing dependencies " echo "=============================================" echo "$(tput sgr0)" # reset -npm install gulp bower -g +npm install gulpjs/gulp.git#4.0 bower -g npm install bower install From 5cce73c1e92be2c99e56067a21d7a0e29f71d424 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 25 Mar 2017 23:39:42 +0100 Subject: [PATCH 7/7] ES6 all the gulp things --- gulpfile.babel.js | 422 ++++++++++++++++++++++------------------------ 1 file changed, 197 insertions(+), 225 deletions(-) diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 9bf571e4..040b42ff 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -4,7 +4,7 @@ const $ = require('gulp-load-plugins')() // manually import modules that won't get picked up by gulp-load-plugins -import gulp from 'gulp' +import { src, dest, watch, parallel, series } from 'gulp' import del from 'del' import pkg from './package.json' import parallelize from 'concurrent-transform' @@ -106,59 +106,24 @@ const BANNER = [ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// gulp tasks -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -// -// Full build -// -// `gulp build` is the development build -// `gulp build --production` is the production build -// -gulp.task('build', gulp.series( - buildBanner, clean, jekyll, - gulp.parallel(html, css, js, images, icons, fonts, media), - rev, revReplace -)) - -function buildBanner(done) { - console.log($.util.colors.gray(" ------------------------------------------")) - console.log($.util.colors.green(' Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')) - console.log($.util.colors.gray(" ------------------------------------------")) - - done() -} - - -// -// Build site, run server, and watch for file changes -// -gulp.task('default', gulp.series('build', server, watch)) - - - -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// Functions +// Tasks // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // // Delete build artifacts // -function clean(done) { - return del([ +export const clean = () => + del([ DIST + '**/*', DIST + '.*', // delete all hidden files '!' + DIST + '/media/**' ]) - done() -} - // // Jekyll // -function jekyll(done) { +export const jekyll = (done) => { browser.notify('Compiling Jekyll') @@ -169,58 +134,53 @@ function jekyll(done) { var jekyll_options = 'jekyll build --config _config.yml,_config.dev.yml --incremental --drafts --future' } - var spawn = require('child_process').spawn, + let spawn = require('child_process').spawn, jekyll = spawn('bundle', ['exec', jekyll_options], { stdio: 'inherit' }) - return jekyll - .on('error', (error) => onError() ) - .on('close', done) + jekyll.on('error', (error) => onError() ).on('close', done) } - // // HTML // -function html() { - return gulp.src(DIST + '/**/*.html') - .pipe($.if(isProduction, $.htmlmin({ - collapseWhitespace: true, - conservativeCollapse: true, - removeComments: true, - useShortDoctype: true, - collapseBooleanAttributes: true, - removeRedundantAttributes: true, - removeEmptyAttributes: true, - minifyJS: true, - minifyCSS: true - }))) - .pipe(gulp.dest(DIST)) -} +export const html = () => src(DIST + '/**/*.html') + .pipe($.if(isProduction, $.htmlmin({ + collapseWhitespace: true, + conservativeCollapse: true, + removeComments: true, + useShortDoctype: true, + collapseBooleanAttributes: true, + removeRedundantAttributes: true, + removeEmptyAttributes: true, + minifyJS: true, + minifyCSS: true + }))) + .pipe(dest(DIST)) // // Styles // -function css() { - - var processors = [ - autoprefixer({ browsers: COMPATIBILITY }), - cssnano() - ] - - return gulp.src([ - SRC + '/_assets/styl/kremalicious3.styl', - SRC + '/_assets/styl/post-*.styl' - ]) - .pipe($.if(!isProduction, $.sourcemaps.init())) - .pipe($.stylus({ 'include css': true })).on('error', onError) - .pipe($.postcss(processors)).on('error', onError) - .pipe($.if(!isProduction, $.sourcemaps.write())) - .pipe($.if(isProduction, $.header(BANNER, { pkg: pkg }))) - .pipe($.rename({ suffix: '.min' })) - .pipe(gulp.dest(DIST + '/assets/css/')) - .pipe(browser.stream()) -} +const processors = [ + autoprefixer({ browsers: COMPATIBILITY }), + cssnano() +] +export const css = () => + src([ + SRC + '/_assets/styl/kremalicious3.styl', + SRC + '/_assets/styl/post-*.styl' + ]) + .pipe($.if(!isProduction, $.sourcemaps.init())) + .pipe($.stylus({ 'include css': true })).on('error', onError) + .pipe($.postcss(processors)).on('error', onError) + .pipe($.if(!isProduction, $.sourcemaps.write())) + .pipe($.if(isProduction, $.header(BANNER, { pkg: pkg }))) + .pipe($.rename({ suffix: '.min' })) + .pipe($.if(isProduction, $.rev())) + .pipe(dest(DIST + '/assets/css/')) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(DIST + '/assets/css/'))) + .pipe(browser.stream()) // @@ -228,63 +188,56 @@ function css() { // // Libraries -function jsLibraries() { - return gulp.src([ - 'node_modules/picturefill/dist/picturefill.js' - ]) - .pipe($.if(isProduction, $.uglify())).on('error', onError) - .pipe($.rename({ suffix: '.min'})) - .pipe(gulp.dest(DIST + '/assets/js/')) -} +const jsLibraries = () => src('node_modules/picturefill/dist/picturefill.js') + .pipe($.if(isProduction, $.uglify())).on('error', onError) + .pipe($.rename({ suffix: '.min'})) + .pipe($.if(isProduction, $.rev())) + .pipe(dest(DIST + '/assets/js/')) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(DIST + '/assets/js/'))) // Project js -function jsProject() { - return gulp.src(SRC + '/_assets/js/kremalicious3.js') - .pipe($.sourcemaps.init()) - .pipe($.include()).on('error', onError) - .pipe($.if(isProduction, $.uglify())).on('error', onError) - .pipe($.if(!isProduction, $.sourcemaps.write())) - .pipe($.if(isProduction, $.header(BANNER, { pkg: pkg }))) - .pipe($.rename({suffix: '.min'})) - .pipe(gulp.dest(DIST + '/assets/js/')) -} +const jsProject = () => src(SRC + '/_assets/js/kremalicious3.js') + .pipe($.sourcemaps.init()) + .pipe($.include()).on('error', onError) + .pipe($.if(isProduction, $.uglify())).on('error', onError) + .pipe($.if(!isProduction, $.sourcemaps.write())) + .pipe($.if(isProduction, $.header(BANNER, { pkg: pkg }))) + .pipe($.rename({suffix: '.min'})) + .pipe($.if(isProduction, $.rev())) + .pipe(dest(DIST + '/assets/js/')) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(DIST + '/assets/js/'))) // Service Worker js -function jsSW() { - return gulp.src(DIST + '/service-worker.js') - .pipe($.if(isProduction, $.uglify({ - compress: { - drop_console: true - } - }))).on('error', onError) - .pipe(gulp.dest(DIST + '/')) -} +const jsSW = () => src(DIST + '/service-worker.js') + .pipe($.if(isProduction, $.uglify({ compress: { drop_console: true } }))).on('error', onError) + .pipe(dest(DIST + '/')) // Collect all script tasks -function js() { - return jsLibraries(), jsProject(), jsSW() -} +export const js = series(jsLibraries, jsProject, jsSW) // // Icons // -function icons() { - return gulp.src(iconset.icons) - .pipe($.rename({ prefix: iconset.prefix })) - .pipe(gulp.dest(iconset.dist)) - .pipe($.filter('**/*.svg')) - .pipe($.if(isProduction, $.imagemin({ svgoPlugins: [{ removeViewBox: false }] }))) - .pipe($.svgSprite(SPRITE)) - .pipe(gulp.dest(iconset.dist)) -} +export const icons = () => src(iconset.icons) + .pipe($.rename({ prefix: iconset.prefix })) + .pipe(dest(iconset.dist)) + .pipe($.filter('**/*.svg')) + .pipe($.if(isProduction, $.imagemin({ svgoPlugins: [{ removeViewBox: false }] }))) + .pipe($.svgSprite(SPRITE)) + .pipe($.if(isProduction, $.rev())) + .pipe(dest(iconset.dist)) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(iconset.dist))) // // Copy images // -function images() { - return gulp.src([ +export const images = () => + src([ SRC + '/_assets/img/**/*', '!' + SRC + '/_assets/img/entypo/**/*' ]) @@ -295,56 +248,41 @@ function images() { multipass: true, // svg svgoPlugins: [{ removeViewBox: false }] }))) - .pipe(gulp.dest(DIST + '/assets/img/')) -} + .pipe($.if(isProduction, $.rev())) + .pipe(dest(DIST + '/assets/img/')) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(DIST + '/assets/img/'))) // // Copy fonts // -function fonts() { - return gulp.src(SRC + '/_assets/fonts/**/*') - .pipe(gulp.dest(DIST + '/assets/fonts/')) -} +export const fonts = () => src(SRC + '/_assets/fonts/**/*') + .pipe($.if(isProduction, $.rev())) + .pipe(dest(DIST + '/assets/fonts/')) + .pipe($.if(isProduction, $.rev.manifest())) + .pipe($.if(isProduction, dest(DIST + '/assets/fonts/'))) // // Copy media // -function media() { - return gulp.src(SRC + '/_media/**/*') - .pipe(gulp.dest(DIST + '/media/')) -} - - -// -// Revision static assets -// -function rev(done) { - // globbing is slow so do everything conditionally for faster dev build - if (isProduction) { - return gulp.src(DIST + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff,woff2}') - .pipe($.if(isProduction, $.rev())) - .pipe(gulp.dest(DIST + '/assets/')) - // output rev manifest for next replace task - .pipe($.if(isProduction, $.rev.manifest())) - .pipe(gulp.dest(DIST + '/assets/')) - } - done() -} +export const media = () => src(SRC + '/_media/**/*') + .pipe(dest(DIST + '/assets/media/')) // // Replace all links to assets in files // from a manifest file // -function revReplace(done) { +export const revReplace = (done) => { + let manifest = src(DIST + '/**/rev-manifest.json') + // globbing is slow so do everything conditionally for faster dev build if (isProduction) { - var manifest = gulp.src(DIST + '/assets/rev-manifest.json') - return gulp.src(DIST + '/**/*.{html,xml,txt,json,css,js,png,jpg,jpeg,svg,eot,ttf,woff}') - .pipe($.if(isProduction, $.revReplace({ manifest: manifest }))) - .pipe(gulp.dest(DIST)) + return src(DIST + '/**/*.{html,css,js}') + .pipe($.revReplace({ manifest: manifest })) + .pipe(dest(DIST)) } done() } @@ -353,13 +291,12 @@ function revReplace(done) { // // Dev Server // -function server(done) { +export const server = (done) => { browser.init({ server: DIST, port: PORT, reloadDebounce: 2000 }) - done() } @@ -367,81 +304,116 @@ function server(done) { // // Watch for file changes // -function watch() { - gulp.watch(SRC + '_assets/styl/**/*.styl').on('all', gulp.series(css)) - gulp.watch(SRC + '_assets/js/**/*.js').on('all', gulp.series(js, browser.reload)) - gulp.watch(SRC + '_assets/img/**/*.{png,jpg,jpeg,gif,webp}').on('all', gulp.series(images, browser.reload)) - gulp.watch(SRC + '_assets/img/**/*.{svg}').on('all', gulp.series(icons, browser.reload)) - gulp.watch(SRC + '_media/**/*').on('all', gulp.series(media, browser.reload)) - gulp.watch([SRC + '/**/*.{html,xml,json,txt,md,yml}', './*.yml', SRC + '_includes/svg/*']).on('all', gulp.series('build', browser.reload)) +export const watchSrc = () => { + watch(SRC + '_assets/styl/**/*.styl').on('all', series(css)) + watch(SRC + '_assets/js/**/*.js').on('all', series(js, browser.reload)) + watch(SRC + '_assets/img/**/*.{png,jpg,jpeg,gif,webp}').on('all', series(images, browser.reload)) + watch(SRC + '_assets/img/**/*.{svg}').on('all', series(icons, browser.reload)) + watch(SRC + '_media/**/*').on('all', series(media, browser.reload)) + watch([SRC + '/**/*.{html,xml,json,txt,md,yml}', './*.yml', SRC + '_includes/svg/*']).on('all', series('build', browser.reload)) } +// +// Build banner +// +export const buildBanner = (done) => { + console.log($.util.colors.gray(" ------------------------------------------")) + console.log($.util.colors.green(' Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')) + console.log($.util.colors.gray(" ------------------------------------------")) + + done() +} + + +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// Collection tasks +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// +// Full build +// +// `gulp build` is the development build +// `gulp build --production` is the production build +// +export const build = series(buildBanner, clean, jekyll, parallel(html, css, js, images, icons, fonts, media), revReplace) + +// +// Build site, run server, and watch for file changes +// +// `gulp dev` +// +export const dev = series(build, server, watchSrc) + +// Set `gulp dev` as default: `gulp` +export default dev + + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Deployment // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -gulp.task('deploy', (done) => { - - // create publisher, define config - var publisher = $.awspublish.create({ - params: { - 'Bucket': S3BUCKET - }, - 'accessKeyId': process.env.AWS_ACCESS_KEY, - 'secretAccessKey': process.env.AWS_SECRET_KEY, - 'region': S3REGION - }) - - return gulp.src(DIST + '/**/*') - .pipe($.awspublishRouter({ - cache: { - // cache for 5 minutes by default - cacheTime: 300 - }, - routes: { - // all static assets, cached & gzipped - '^assets/(?:.+)\\.(?:js|css|png|jpg|jpeg|gif|ico|svg|ttf|eot|woff|woff2)$': { - cacheTime: 2592000, // cache for 1 month - gzip: true - }, - - // every other asset, cached - '^assets/.+$': { - cacheTime: 2592000 // cache for 1 month - }, - - // all html files, not cached & gzipped - '^.+\\.html': { - cacheTime: 0, - gzip: true - }, - - // font mime types - '\.ttf$': { - key: '$&', - headers: { 'Content-Type': 'application/x-font-ttf' } - }, - '\.woff$': { - key: '$&', - headers: { 'Content-Type': 'application/x-font-woff' } - }, - '\.woff2$': { - key: '$&', - headers: { 'Content-Type': 'application/x-font-woff2' } - }, - - // pass-through for anything that wasn't matched by routes above, to be uploaded with default options - "^.+$": "$&" - } - })) - // make sure everything goes to the root '/' - .pipe($.rename(function (path) { - path.dirname = S3PATH + path.dirname - })) - .pipe(parallelize(publisher.publish(), 100)) - .pipe(publisher.sync()) // delete files in bucket that are not in local folder - .pipe($.awspublish.reporter({ - states: ['create', 'update', 'delete'] - })) +// create publisher, define config +const publisher = $.awspublish.create({ + params: { + 'Bucket': S3BUCKET + }, + 'accessKeyId': process.env.AWS_ACCESS_KEY, + 'secretAccessKey': process.env.AWS_SECRET_KEY, + 'region': S3REGION }) + +export const s3 = () => src(DIST + '/**/*') + .pipe($.awspublishRouter({ + cache: { + // cache for 5 minutes by default + cacheTime: 300 + }, + routes: { + // all static assets, cached & gzipped + '^assets/(?:.+)\\.(?:js|css|png|jpg|jpeg|gif|ico|svg|ttf|eot|woff|woff2)$': { + cacheTime: 2592000, // cache for 1 month + gzip: true + }, + + // every other asset, cached + '^assets/.+$': { + cacheTime: 2592000 // cache for 1 month + }, + + // all html files, not cached & gzipped + '^.+\\.html': { + cacheTime: 0, + gzip: true + }, + + // font mime types + '\.ttf$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-ttf' } + }, + '\.woff$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-woff' } + }, + '\.woff2$': { + key: '$&', + headers: { 'Content-Type': 'application/x-font-woff2' } + }, + + // pass-through for anything that wasn't matched by routes above, to be uploaded with default options + "^.+$": "$&" + } + })) + // make sure everything goes to the root '/' + .pipe($.rename(function (path) { + path.dirname = S3PATH + path.dirname + })) + .pipe(parallelize(publisher.publish(), 100)) + .pipe(publisher.sync()) // delete files in bucket that are not in local folder + .pipe($.awspublish.reporter({ + states: ['create', 'update', 'delete'] + })) + +// `gulp deploy` +export const deploy = series(s3)