From c9a1339efbdcf2f8dd2937aee102a837eab4c2a4 Mon Sep 17 00:00:00 2001 From: Sondre Nilsen Date: Tue, 25 Aug 2015 00:52:16 +0200 Subject: [PATCH] Overhauled the Gulpfile Fixed a bunch of minor problems with generating JS and CSS, removed the cache buster for now because of how much of a pain in the ass it has been, renamed some JS files and removed Useref and now use gulp-inject instead do directly inject assets. Also updated tests accordingly. --- generators/gulp/templates/gulpfile.babel.js | 232 ++++++++++-------- .../jekyll/templates/app/_includes/head.html | 6 +- .../templates/app/_layouts/default.html | 6 +- .../templates/app/assets/javascript/main.js | 1 + .../app/assets/javascript/somejavascript.js | 0 .../javascript/{javascript.js => vendor.js} | 2 + test/gulp.js | 9 +- 7 files changed, 150 insertions(+), 106 deletions(-) create mode 100644 generators/jekyll/templates/app/assets/javascript/main.js delete mode 100644 generators/jekyll/templates/app/assets/javascript/somejavascript.js rename generators/jekyll/templates/app/assets/javascript/{javascript.js => vendor.js} (65%) diff --git a/generators/gulp/templates/gulpfile.babel.js b/generators/gulp/templates/gulpfile.babel.js index 8fbeaa0..c54ee0b 100755 --- a/generators/gulp/templates/gulpfile.babel.js +++ b/generators/gulp/templates/gulpfile.babel.js @@ -5,8 +5,8 @@ import gulp from 'gulp'; // to call them as $.pluginname import gulpLoadPlugins from 'gulp-load-plugins'; const $ = gulpLoadPlugins(); -// 'trash' is used to clean out directories and such -import trash from 'trash'; +// Delete stuff +import del from 'del'; // Used to run shell commands import shell from 'shelljs'; <% if (amazonS3) { -%> @@ -18,99 +18,136 @@ import parallelize from 'concurrent-transform'; // BrowserSync is used to live-reload your website import browserSync from 'browser-sync'; const reload = browserSync.reload; -// merge is used to merge the output from two different streams into the same stream -import merge from 'merge-stream'; -// Wiredep is used to automatically wire up your Bower dependencies +// 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'; // Deletes the directory that the optimized site is output to -gulp.task('clean:dist', cb => { trash(['dist']); cb(); }); //eslint-disable-line -gulp.task('clean:assets', cb => { trash(['.tmp']); cb(); }); //eslint-disable-line -gulp.task('clean:metadata', cb => { trash(['src/.jekyll-metadata']); cb(); }); //eslint-disable-line +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})); // Tasks for building Jekyll, either with development settings (drafts etc) or // with production settings -gulp.task('jekyll:dev', cb => { +gulp.task('jekyll:dev', done => { shell.exec('jekyll build --quiet'); - cb(); + done(); }); -gulp.task('jekyll:prod', cb => { +gulp.task('jekyll:prod', done => { shell.exec('jekyll build --quiet --config _config.yml,_config.build.yml'); - cb(); + done(); }); -// Compiles the SASS files and moves them into the 'assets/stylesheets' directory -gulp.task('styles', () => { - // Looks at the style.scss file for what to include and creates a style.css file - return gulp.src('src/assets/scss/style.scss') - // Start creation of sourcemaps +gulp.task('styles', () => + gulp.src('src/assets/scss/style.scss') + .pipe($.changed('.tmp/assets/stylesheets', {extension: '.css'})) .pipe($.sourcemaps.init()) - .pipe($.sass({errLogToconsole: true})) - // AutoPrefix your CSS so it works between browsers - .pipe($.autoprefixer('last 1 version', {cascade: true})) - // Write the sourcemaps to the directory of the gulp.src stream - .pipe($.sourcemaps.write('.')) - // Directory your CSS file goes to + .pipe($.sass({ + precision: 10 + }).on('error', $.sass.logError)) + .pipe($.postcss([ + autoprefixer({browsers: 'last 1 version'}) + ])) + .pipe($.sourcemaps.write()) + .pipe($.size({ + title: 'styles', + showFiles: true + })) .pipe(gulp.dest('.tmp/assets/stylesheets')) - // Outputs the size of the CSS file - .pipe($.size({title: 'styles'})) - // Injects the CSS changes to your browser since Jekyll doesn't rebuild the CSS - .pipe(reload({stream: true})); -}); - -// Mostly used to create sourcemaps and live-reload JS -gulp.task('javascript', () => { - return gulp.src('src/assets/javascript/**/*.js') - .pipe($.sourcemaps.init()) - .pipe($.uglify({compress: false, preserveComments: 'all'})) - .pipe($.groupConcat({ - 'index.js': 'src/assets/javascript/**/*.js' - })) + .pipe($.if('*.css', $.minifyCss())) .pipe($.sourcemaps.write('.')) + .pipe($.size({ + title: 'optimized styles', + showFiles: true + })) + .pipe($.rename('style.min.css')) + .pipe(gulp.dest('dist/assets/stylesheets')) + .pipe($.if('*.css', $.gzip({append: true}))) + .pipe($.size({ + title: 'gzipped styles', + gzip: true, + showFiles: true + })) + .pipe(gulp.dest('dist/assets/stylesheets')) +); + +gulp.task('javascript', () => + gulp.src([ + 'src/assets/javascript/vendor.js', + 'src/assets/javascript/main.js' + ]) + .pipe($.changed('.tmp/assets/javascript', {extension: '.js'})) + .pipe($.sourcemaps.init()) + .pipe($.concat('index.js')) + .pipe($.sourcemaps.write()) + .pipe($.size({ + title: 'scripts', + showFiles: true + })) .pipe(gulp.dest('.tmp/assets/javascript')) - .pipe($.size({title: 'javascript'})) - .pipe(reload({stream: true})); -}); + .pipe($.sourcemaps.write('.')) + .pipe($.if('*.js', $.uglify({preserveComments: 'some'}))) + .pipe($.size({ + title: 'optimized scripts', + showFiles: true + })) + .pipe($.rename('index.min.js')) + .pipe(gulp.dest('dist/assets/javascript')) + .pipe($.if('*.js', $.gzip({append: true}))) + .pipe($.size({ + title: 'gzipped script', + gzip: true, + showFiles: true + })) + .pipe(gulp.dest('dist/assets/javascript')) +); -// Optimizes the images that exists -gulp.task('images', () => { - return gulp.src('src/assets/images/**/*') - // Does not run on images that are already optimized +gulp.task('html', () => + gulp.src('dist/**/*.html') + .pipe($.htmlmin({ + removeComments: true, + collapseWhitespace: true, + collapseBooleanAttributes: true, + removeAttributeQuotes: true, + removeRedundantAttributes: true + })) + .pipe($.size({title: 'optimized HTML'})) + .pipe($.gzip({append: true})) + .pipe(gulp.dest('dist')) +); + +gulp.task('inject:head', () => + gulp.src('src/_includes/head.html') + .pipe($.inject(gulp.src('dist/assets/stylesheets/*.css', {read: false}))) + .pipe(gulp.dest('src/_includes')) +); + +gulp.task('inject:footer', () => + gulp.src('src/_layouts/default.html') + .pipe($.inject(gulp.src('dist/assets/javascript/*.js', {read: false}))) + .pipe(gulp.dest('src/_layouts')) +); + +gulp.task('images', () => + gulp.src('src/assets/images/**/*') .pipe($.cache($.imagemin({ - // Lossless conversion to progressive JPGs progressive: true, - // Interlace GIFs for progressive rendering interlaced: true }))) .pipe(gulp.dest('.tmp/assets/images')) - .pipe($.size({title: 'images'})); -}); - -// Copy over fonts to the '.tmp' directory -gulp.task('fonts', () => { - return gulp.src('src/assets/fonts/**/*') - .pipe(gulp.dest('.tmp/assets/font')) - .pipe($.size({title: 'fonts'})); -}); - -// Copy optimized images, vendor assets and fonts to the 'dist' folder -gulp.task('copy', () => { - const vendor = gulp.src('.tmp/assets/vendor/**/') - .pipe(gulp.dest('dist/assets/vendor')) - .pipe($.size({title: 'vendor assets'})); - - const images = gulp.src('.tmp/assets/images/**/') .pipe(gulp.dest('dist/assets/images')) - .pipe($.size({title: 'copied images'})); + .pipe($.size({title: 'images'})) +); - const fonts = gulp.src('.tmp/assets/fonts/**/') +gulp.task('fonts', () => + gulp.src('src/assets/fonts/**/*') .pipe(gulp.dest('dist/assets/fonts')) - .pipe($.size({title: 'copied fonts'})); - - return merge(vendor, images, fonts); -}); + .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 @@ -126,12 +163,10 @@ gulp.task('bower', () => { html: { replace: { js: filePath => { - return ''; + return ''; }, css: filePath => { - return ''; + return ''; } } } @@ -276,42 +311,49 @@ gulp.task('deploy', () => { <% } -%> <% if (noUpload) { -%><% } -%> -// Run JS Lint against your JS -gulp.task('jslint', () => { - gulp.src('.tmp/assets/javascript/*.js') - // Checks your JS code quality against your .jshintrc file - .pipe($.jshint('.jshintrc')) - .pipe($.jshint.reporter()); -}); +gulp.task('lint', () => + gulp.src([ + 'gulpfile.babel.js', + '.tmp/assets/javascript/*.js' + ]) + .pipe($.eslint()) + .pipe($.eslint.formatEach()) + .pipe($.eslint.failOnError()) +); // Runs 'jekyll doctor' on your site to check for errors with your configuration // and will check for URL errors a well -gulp.task('doctor', cb => { shell.exec('jekyll doctor'); cb(); }); //eslint-disable-line +gulp.task('doctor', done => { shell.exec('jekyll doctor'); done(); }); //eslint-disable-line // 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({ - notify: true, // tunnel: true, server: { - baseDir: ['dist', '.tmp'] + 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')); - gulp.watch('src/assets/scss/**/*.scss', gulp.series('styles')); + gulp.watch(['src/**/*.md', 'src/**/*.html', 'src/**/*.xml', + 'src/**/*.txt', 'src/**/*.yml']).on('change', reload); + gulp.watch('src/assets/javascript/**/*.js', gulp.series('javascript', reload)); + gulp.watch('src/assets/scss/**/*.scss', gulp.series('styles', reload)); gulp.watch('src/assets/images/**/*', reload); }); +gulp.task('serve:dist', () => { + browserSync({ + notify: true, + server: { + baseDir: ['dist'] + } + }); +}); + // Default task, run when just writing 'gulp' in the terminal gulp.task('default', gulp.series( gulp.series('jekyll:dev'), @@ -323,8 +365,7 @@ gulp.task('default', gulp.series( // it and outputs it to './dist' gulp.task('optimize', gulp.series( gulp.series('jekyll:prod'), - gulp.parallel('styles', 'javascript', 'fonts', 'images', 'copy'), - gulp.series('optimize') + gulp.parallel('styles', 'javascript', 'fonts', 'images') )); gulp.task('build', gulp.series( @@ -333,8 +374,7 @@ gulp.task('build', gulp.series( )); // Clean out your dist and .tmp folder and delete .jekyll-metadata -gulp.task('rebuild', gulp.series('clean:dist', 'clean:assets', - 'clean: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('doctor', 'jslint')); +gulp.task('check', gulp.series('doctor', 'lint')); diff --git a/generators/jekyll/templates/app/_includes/head.html b/generators/jekyll/templates/app/_includes/head.html index 367a74d..23e5fa5 100644 --- a/generators/jekyll/templates/app/_includes/head.html +++ b/generators/jekyll/templates/app/_includes/head.html @@ -8,10 +8,10 @@ - - + + + {% include bower_styles.html %} - diff --git a/generators/jekyll/templates/app/_layouts/default.html b/generators/jekyll/templates/app/_layouts/default.html index eaee562..a5b02a3 100644 --- a/generators/jekyll/templates/app/_layouts/default.html +++ b/generators/jekyll/templates/app/_layouts/default.html @@ -16,10 +16,10 @@ {% include footer.html %} - - + + + {% include bower_scripts.html %} - diff --git a/generators/jekyll/templates/app/assets/javascript/main.js b/generators/jekyll/templates/app/assets/javascript/main.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/generators/jekyll/templates/app/assets/javascript/main.js @@ -0,0 +1 @@ + diff --git a/generators/jekyll/templates/app/assets/javascript/somejavascript.js b/generators/jekyll/templates/app/assets/javascript/somejavascript.js deleted file mode 100644 index e69de29..0000000 diff --git a/generators/jekyll/templates/app/assets/javascript/javascript.js b/generators/jekyll/templates/app/assets/javascript/vendor.js similarity index 65% rename from generators/jekyll/templates/app/assets/javascript/javascript.js rename to generators/jekyll/templates/app/assets/javascript/vendor.js index b9d3e23..7e6a672 100644 --- a/generators/jekyll/templates/app/assets/javascript/javascript.js +++ b/generators/jekyll/templates/app/assets/javascript/vendor.js @@ -1 +1,3 @@ +'use strict'; + console.log('Hello world!'); diff --git a/test/gulp.js b/test/gulp.js index 5a54f1f..adac860 100644 --- a/test/gulp.js +++ b/test/gulp.js @@ -91,13 +91,14 @@ describe('jekyllized:gulp', function() { ['gulpfile.babel.js', /gulp.task\(\'jekyll\:prod\'/], ['gulpfile.babel.js', /gulp.task\(\'styles\'/], ['gulpfile.babel.js', /gulp.task\(\'javascript\'/], + ['gulpfile.babel.js', /gulp.task\(\'html\'/], + ['gulpfile.babel.js', /gulp.task\(\'inject\:head\'/], + ['gulpfile.babel.js', /gulp.task\(\'inject\:footer\'/], ['gulpfile.babel.js', /gulp.task\(\'images\'/], ['gulpfile.babel.js', /gulp.task\(\'fonts\'/], - ['gulpfile.babel.js', /gulp.task\(\'copy\'/], ['gulpfile.babel.js', /gulp.task\(\'bower\'/], ['gulpfile.babel.js', /gulp.task\(\'bower:files\'/], - ['gulpfile.babel.js', /gulp.task\(\'optimize\'/], - ['gulpfile.babel.js', /gulp.task\(\'jslint\'/], + ['gulpfile.babel.js', /gulp.task\(\'lint\'/], ['gulpfile.babel.js', /gulp.task\(\'doctor\'/], ['gulpfile.babel.js', /gulp.task\(\'default\'/], ['gulpfile.babel.js', /gulp.task\(\'build\'/], @@ -246,7 +247,7 @@ describe('jekyllized:gulp', function() { assert.fileContent('gulpfile.babel.js', /\/\/ Task to upload your site to your personal GH Pages repo/); }); - it('does not contain the wrong uploadgin task', function() { + it('does not contain the wrong uploading task', function() { assert.noFileContent('gulpfile.babel.js', /\/\/ Task to upload your site via Rsync to your server/); assert.noFileContent('gulpfile.babel.js', /\/\/ Task to deploy your site to Amazon S3 and Cloudfront/); });