Skip to content

Instantly share code, notes, and snippets.

@raisiqueira
Created June 1, 2016 18:05
Show Gist options
  • Save raisiqueira/03fe58e2fc0d5254f1714b383c81af4a to your computer and use it in GitHub Desktop.
Save raisiqueira/03fe58e2fc0d5254f1714b383c81af4a to your computer and use it in GitHub Desktop.
Gulpfile.js ES2015
/**
*
* Web Starter Kit
* Copyright 2015 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*
*/
'use strict';
// This gulpfile makes use of new JavaScript features.
// Babel handles this without us having to do anything. It just works.
// You can read more about the new JavaScript features here:
// https://babeljs.io/docs/learn-es2015/
import path from 'path';
import gulp from 'gulp';
import del from 'del';
import runSequence from 'run-sequence';
import browserSync from 'browser-sync';
import swPrecache from 'sw-precache';
import gulpLoadPlugins from 'gulp-load-plugins';
import {output as pagespeed} from 'psi';
import pkg from './package.json';
const $ = gulpLoadPlugins();
const reload = browserSync.reload;
// Lint JavaScript
gulp.task('lint', () =>
gulp.src('app/scripts/**/*.js')
.pipe($.eslint())
.pipe($.eslint.format())
.pipe($.if(!browserSync.active, $.eslint.failOnError()))
);
// Optimize images
gulp.task('images', () =>
gulp.src('app/images/**/*')
.pipe($.cache($.imagemin({
progressive: true,
interlaced: true
})))
.pipe(gulp.dest('dist/images'))
.pipe($.size({title: 'images'}))
);
// Copy all files at the root level (app)
gulp.task('copy', () =>
gulp.src([
'app/*',
'!app/*.html',
'node_modules/apache-server-configs/dist/.htaccess'
], {
dot: true
}).pipe(gulp.dest('dist'))
.pipe($.size({title: 'copy'}))
);
// Compile and automatically prefix stylesheets
gulp.task('styles', () => {
const AUTOPREFIXER_BROWSERS = [
'ie >= 10',
'ie_mob >= 10',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 4.4',
'bb >= 10'
];
// For best performance, don't add Sass partials to `gulp.src`
return gulp.src([
'app/styles/**/*.scss',
'app/styles/**/*.css'
])
.pipe($.newer('.tmp/styles'))
.pipe($.sourcemaps.init())
.pipe($.sass({
precision: 10
}).on('error', $.sass.logError))
.pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
.pipe(gulp.dest('.tmp/styles'))
// Concatenate and minify styles
.pipe($.if('*.css', $.cssnano()))
.pipe($.size({title: 'styles'}))
.pipe($.sourcemaps.write('./'))
.pipe(gulp.dest('dist/styles'));
});
// Concatenate and minify JavaScript. Optionally transpiles ES2015 code to ES5.
// to enable ES2015 support remove the line `"only": "gulpfile.babel.js",` in the
// `.babelrc` file.
gulp.task('scripts', () =>
gulp.src([
// Note: Since we are not using useref in the scripts build pipeline,
// you need to explicitly list your scripts here in the right order
// to be correctly concatenated
'./app/scripts/main.js'
// Other scripts
])
.pipe($.newer('.tmp/scripts'))
.pipe($.sourcemaps.init())
.pipe($.babel())
.pipe($.sourcemaps.write())
.pipe(gulp.dest('.tmp/scripts'))
.pipe($.concat('main.min.js'))
.pipe($.uglify({preserveComments: 'some'}))
// Output files
.pipe($.size({title: 'scripts'}))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest('dist/scripts'))
);
// Scan your HTML for assets & optimize them
gulp.task('html', () => {
return gulp.src('app/**/*.html')
.pipe($.useref({searchPath: '{.tmp,app}'}))
// Remove any unused CSS
.pipe($.if('*.css', $.uncss({
html: [
'app/index.html'
],
// CSS Selectors for UnCSS to ignore
ignore: []
})))
// Concatenate and minify styles
// In case you are still using useref build blocks
.pipe($.if('*.css', $.cssnano()))
// Minify any HTML
.pipe($.if('*.html', $.htmlmin({
removeComments: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
removeOptionalTags: true
})))
// Output files
.pipe($.if('*.html', $.size({title: 'html', showFiles: true})))
.pipe(gulp.dest('dist'));
});
// Clean output directory
gulp.task('clean', () => del(['.tmp', 'dist/*', '!dist/.git'], {dot: true}));
// Watch files for changes & reload
gulp.task('serve', ['scripts', 'styles'], () => {
browserSync({
notify: false,
// Customize the Browsersync console logging prefix
logPrefix: 'WSK',
// Allow scroll syncing across breakpoints
scrollElementMapping: ['main', '.mdl-layout'],
// 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: ['.tmp', 'app'],
port: 3000
});
gulp.watch(['app/**/*.html'], reload);
gulp.watch(['app/styles/**/*.{scss,css}'], ['styles', reload]);
gulp.watch(['app/scripts/**/*.js'], ['lint', 'scripts']);
gulp.watch(['app/images/**/*'], reload);
});
// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], () =>
browserSync({
notify: false,
logPrefix: 'WSK',
// Allow scroll syncing across breakpoints
scrollElementMapping: ['main', '.mdl-layout'],
// 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',
port: 3001
})
);
// Build production files, the default task
gulp.task('default', ['clean'], cb =>
runSequence(
'styles',
['lint', 'html', 'scripts', 'images', 'copy'],
'generate-service-worker',
cb
)
);
// Run PageSpeed Insights
gulp.task('pagespeed', cb =>
// Update the below URL to the public URL of your site
pagespeed('example.com', {
strategy: 'mobile'
// By default we use the PageSpeed Insights free (no API key) tier.
// Use a Google Developer API key if you have one: http://goo.gl/RkN0vE
// key: 'YOUR_API_KEY'
}, cb)
);
// Copy over the scripts that are used in importScripts as part of the generate-service-worker task.
gulp.task('copy-sw-scripts', () => {
return gulp.src(['node_modules/sw-toolbox/sw-toolbox.js', 'app/scripts/sw/runtime-caching.js'])
.pipe(gulp.dest('dist/scripts/sw'));
});
// See http://www.html5rocks.com/en/tutorials/service-worker/introduction/ for
// an in-depth explanation of what service workers are and why you should care.
// Generate a service worker file that will provide offline functionality for
// local resources. This should only be done for the 'dist' directory, to allow
// live reload to work as expected when serving from the 'app' directory.
gulp.task('generate-service-worker', ['copy-sw-scripts'], () => {
const rootDir = 'dist';
const filepath = path.join(rootDir, 'service-worker.js');
return swPrecache.write(filepath, {
// Used to avoid cache conflicts when serving on localhost.
cacheId: pkg.name || 'web-starter-kit',
// sw-toolbox.js needs to be listed first. It sets up methods used in runtime-caching.js.
importScripts: [
'scripts/sw/sw-toolbox.js',
'scripts/sw/runtime-caching.js'
],
staticFileGlobs: [
// Add/remove glob patterns to match your directory setup.
`${rootDir}/images/**/*`,
`${rootDir}/scripts/**/*.js`,
`${rootDir}/styles/**/*.css`,
`${rootDir}/*.{html,json}`
],
// Translates a static file path to the relative URL that it's served from.
// This is '/' rather than path.sep because the paths returned from
// glob always use '/'.
stripPrefix: rootDir + '/'
});
});
// Load custom tasks from the `tasks` directory
// Run: `npm install --save-dev require-dir` from the command-line
// try { require('require-dir')('tasks'); } catch (err) { console.error(err); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment