snapdrop/gulpfile.js
2015-12-26 13:33:16 +01:00

341 lines
10 KiB
JavaScript

'use strict';
// Include Gulp & tools we'll use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var merge = require('merge-stream');
var path = require('path');
var fs = require('fs');
var glob = require('glob-all');
var historyApiFallback = require('connect-history-api-fallback');
var packageJson = require('./package.json');
var crypto = require('crypto');
var ensureFiles = require('./tasks/ensure-files.js');
var inlinesource = require('gulp-inline-source');
var proxy = require('proxy-middleware');
var url = require('url');
var minifyHTML = require('gulp-minify-html');
// var ghPages = require('gulp-gh-pages');
var AUTOPREFIXER_BROWSERS = [
'ie >= 10',
'ie_mob >= 10',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 4.4',
'bb >= 10'
];
var DIST = 'dist';
var dist = function(subpath) {
return !subpath ? DIST : path.join(DIST, subpath);
};
var styleTask = function(stylesPath, srcs) {
return gulp.src(srcs.map(function(src) {
return path.join('app', stylesPath, src);
}))
.pipe($.changed(stylesPath, {
extension: '.css'
}))
.pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
.pipe(gulp.dest('.tmp/' + stylesPath))
.pipe($.minifyCss())
.pipe(gulp.dest(dist(stylesPath)))
.pipe($.size({
title: stylesPath
}));
};
var imageOptimizeTask = function(src, dest) {
return gulp.src(src)
.pipe($.imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest(dest))
.pipe($.size({
title: 'images'
}));
};
var optimizeHtmlTask = function(src, dest) {
var assets = $.useref.assets({
searchPath: ['.tmp', 'app']
});
return gulp.src(src)
.pipe(assets)
// Concatenate and minify JavaScript
.pipe($.if('*.js', $.uglify({
preserveComments: 'some'
})))
// Concatenate and minify styles
// In case you are still using useref build blocks
.pipe($.if('*.css', $.minifyCss()))
.pipe(assets.restore())
.pipe($.useref())
// Minify any HTML
.pipe($.if('*.html', $.minifyHtml({
quotes: true,
empty: true,
spare: true
})))
.pipe($.if('*.html', inlinesource()))
// Output files
.pipe(gulp.dest(dest))
.pipe($.size({
title: 'html'
}));
};
// Compile and automatically prefix stylesheets
gulp.task('styles', function() {
return styleTask('styles', ['**/*.css']);
});
gulp.task('elements', function() {
return styleTask('elements', ['**/*.css']);
});
// Ensure that we are not missing required files for the project
// "dot" files are specifically tricky due to them being hidden on
// some systems.
gulp.task('ensureFiles', function(cb) {
var requiredFiles = ['.jscsrc', '.jshintrc', '.bowerrc'];
ensureFiles(requiredFiles.map(function(p) {
return path.join(__dirname, p);
}), cb);
});
// Lint JavaScript
gulp.task('lint', ['ensureFiles'], function() {
return gulp.src([
'app/scripts/**/*.js',
'app/elements/**/*.js',
'app/elements/**/*.html',
'gulpfile.js'
])
.pipe(reload({
stream: true,
once: true
}))
// JSCS has not yet a extract option
.pipe($.if('*.html', $.htmlExtract()))
.pipe($.jshint())
.pipe($.jscs())
.pipe($.jscsStylish.combineWithHintResults())
.pipe($.jshint.reporter('jshint-stylish'))
.pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});
// Optimize images
gulp.task('images', function() {
return imageOptimizeTask('app/images/**/*', dist('images'));
});
// Copy all files at the root level (app)
gulp.task('copy', function() {
var app = gulp.src([
'app/*',
'!app/test',
'!app/elements',
'!app/bower_components',
'!app/cache-config.json'
], {
dot: true
}).pipe(gulp.dest(dist()));
// Copy over only the bower_components we need
// These are things which cannot be vulcanized
var bower = gulp.src([
'app/bower_components/{webcomponentsjs,platinum-sw,sw-toolbox,promise-polyfill}/**/*'
]).pipe(gulp.dest(dist('bower_components')));
return merge(app, bower)
.pipe($.size({
title: 'copy'
}));
});
// Copy web fonts to dist
gulp.task('fonts', function() {
return gulp.src(['app/fonts/**'])
.pipe(gulp.dest(dist('fonts')))
.pipe($.size({
title: 'fonts'
}));
});
// Scan your HTML for assets & optimize them
gulp.task('html', function() {
return optimizeHtmlTask(
['app/**/*.html', '!app/{elements,test,bower_components}/**/*.html'],
dist());
});
// Vulcanize granular configuration
gulp.task('vulcanize', function() {
return gulp.src('app/elements/elements.html')
.pipe($.vulcanize({
stripComments: true,
inlineCss: true,
inlineScripts: true
}))
.pipe(minifyHTML({ empty: true }))
.pipe(gulp.dest(dist('elements')))
.pipe($.size({
title: 'vulcanize'
}));
});
// Generate config data for the <sw-precache-cache> element.
// This include a list of files that should be precached, as well as a (hopefully unique) cache
// id that ensure that multiple PSK projects don't share the same Cache Storage.
// This task does not run by default, but if you are interested in using service worker caching
// in your project, please enable it within the 'default' task.
// See https://github.com/PolymerElements/polymer-starter-kit#enable-service-worker-support
// for more context.
gulp.task('cache-config', function(callback) {
var dir = dist();
var config = {
cacheId: packageJson.name || path.basename(__dirname),
disabled: false
};
glob([
'index.html',
'./',
'bower_components/webcomponentsjs/webcomponents-lite.min.js',
'{elements,scripts,styles}/**/*.*'
], {
cwd: dir
}, function(error, files) {
if (error) {
callback(error);
} else {
config.precache = files;
var md5 = crypto.createHash('md5');
md5.update(JSON.stringify(config.precache));
config.precacheFingerprint = md5.digest('hex');
var configPath = path.join(dir, 'cache-config.json');
fs.writeFile(configPath, JSON.stringify(config), callback);
}
});
});
// Clean output directory
gulp.task('clean', function() {
return del(['.tmp', dist()]);
});
// Watch files for changes & reload
gulp.task('serve', ['styles', 'elements', 'images'], function() {
var peerjsProxy = url.parse('http://localhost:3002/peerjs');
peerjsProxy.route = '/peerjs';
var websocketProxy = url.parse('http://localhost:3002/binary');
websocketProxy.route = '/binary';
browserSync({
port: 5000,
notify: false,
logPrefix: 'PSK',
ghostMode: false,
snippetOptions: {
rule: {
match: '<span id="browser-sync-binding"></span>',
fn: function(snippet) {
return snippet;
}
}
},
// Run as an https by uncommenting 'https: true'
// Note: this uses an unsigned certificate which on first access
// will present a certificate warning in the browser.
// https: true,
server: {
baseDir: ['.tmp', 'app'],
middleware: [proxy(peerjsProxy),proxy(websocketProxy), historyApiFallback()]
}
});
gulp.watch(['app/**/*.html'], reload);
gulp.watch(['app/styles/**/*.css'], ['styles', reload]);
gulp.watch(['app/elements/**/*.css'], ['elements', reload]);
gulp.watch(['app/{scripts,elements}/**/{*.js,*.html}'], ['lint']);
gulp.watch(['app/images/**/*'], reload);
});
// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function() {
browserSync({
port: 5001,
notify: false,
logPrefix: 'PSK',
snippetOptions: {
rule: {
match: '<span id="browser-sync-binding"></span>',
fn: function(snippet) {
return snippet;
}
}
},
// Run as an https by uncommenting 'https: true'
// Note: this uses an unsigned certificate which on first access
// will present a certificate warning in the browser.
// https: true,
server: dist(),
middleware: [historyApiFallback()]
});
});
// Build production files, the default task
gulp.task('default', ['clean'], function(cb) {
// Uncomment 'cache-config' if you are going to use service workers.
runSequence(
['copy', 'styles'],
'elements', ['images', 'fonts', 'html'], //'lint',
'vulcanize', 'cache-config',
cb);
});
// Build then deploy to GitHub pages gh-pages branch
gulp.task('build-deploy-gh-pages', function(cb) {
runSequence(
'default',
'deploy-gh-pages',
cb);
});
// Deploy to GitHub pages gh-pages branch
gulp.task('deploy-gh-pages', function() {
return gulp.src(dist('**/*'))
// Check if running task from Travis CI, if so run using GH_TOKEN
// otherwise run using ghPages defaults.
.pipe($.if(process.env.TRAVIS === 'true', $.ghPages({
remoteUrl: 'https://$GH_TOKEN@github.com/polymerelements/polymer-starter-kit.git',
silent: true,
branch: 'gh-pages'
}), $.ghPages()));
});
// Load tasks for web-component-tester
// Adds tasks for `gulp test:local` and `gulp test:remote`
require('web-component-tester').gulp.init(gulp);
// Load custom tasks from the `tasks` directory
try {
require('require-dir')('tasks');
} catch (err) {}