246 строки
7.5 KiB
JavaScript
Executable File
246 строки
7.5 KiB
JavaScript
Executable File
'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 swPrecache from 'sw-precache';
|
|
import gulpLoadPlugins from 'gulp-load-plugins';
|
|
import merge from 'merge-stream';
|
|
import cssslam from 'css-slam';
|
|
|
|
const $ = gulpLoadPlugins();
|
|
|
|
function minifyHtml() {
|
|
return $.minifyHtml({
|
|
quotes: true,
|
|
empty: true,
|
|
spare: true
|
|
}).on('error', console.log.bind(console));
|
|
}
|
|
|
|
function uglifyJS() {
|
|
return $.uglify({preserveComments: 'some'});
|
|
}
|
|
|
|
function license() {
|
|
return $.license('Apache2', {
|
|
organization: 'Copyright (c) 2016 The Google Inc. All rights reserved.',
|
|
tiny: true
|
|
});
|
|
}
|
|
|
|
gulp.task('lint', () => {
|
|
return gulp.src([
|
|
'static/**/*.js'
|
|
])
|
|
.pipe($.eslint())
|
|
.pipe($.eslint.format())
|
|
.pipe($.eslint.failAfterError());
|
|
});
|
|
|
|
// Compile and automatically prefix stylesheets
|
|
gulp.task('styles', () => {
|
|
const AUTOPREFIXER_BROWSERS = [
|
|
'last 1 version',
|
|
'last 2 iOS versions'
|
|
];
|
|
|
|
// For best performance, don't add Sass partials to `gulp.src`
|
|
return gulp.src([
|
|
'static/sass/**/*.scss'
|
|
])
|
|
.pipe($.sass({
|
|
outputStyle: 'compressed',
|
|
precision: 10
|
|
}).on('error', $.sass.logError))
|
|
.pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
|
|
.pipe(gulp.dest('static/css'));
|
|
});
|
|
|
|
// Run scripts through babel. Note, this does not include vulcanized js.
|
|
gulp.task('js', () => {
|
|
return gulp.src([
|
|
//'static/elements/*.vulcanize.js',
|
|
'static/js/**/*.es6.js',
|
|
])
|
|
.pipe($.babel()) // Defaults are in .babelrc
|
|
.pipe(uglifyJS())
|
|
.pipe(license()) // Add license to top.
|
|
.pipe($.rename({suffix: '.min'}))
|
|
.pipe(gulp.dest('static/js'));
|
|
});
|
|
|
|
// Vulcanize the Polymer imports, creating *.vulcanize.* files beside the
|
|
// original import files.
|
|
gulp.task('vulcanize-lazy-elements', () => {
|
|
return gulp.src([
|
|
'static/bower_components/paper-menu-button/paper-menu-button.html',
|
|
'static/elements/chromedash-legend.html'
|
|
])
|
|
.pipe($.vulcanize({
|
|
stripComments: true,
|
|
inlineScripts: true,
|
|
inlineCss: true,
|
|
// Leave out elements registered by main site or shared in other
|
|
// lazy-loaded elements.
|
|
stripExcludes: [
|
|
'polymer.html$',
|
|
'iron-meta.html',
|
|
'chromedash-color-status.html'
|
|
]
|
|
}))
|
|
.pipe($.rename({suffix: '.vulcanize'}))
|
|
.pipe($.crisper({scriptInHead: true})) // Separate HTML and JS. CSP friendly.
|
|
.pipe($.if('*.html', minifyHtml())) // Minify HTML output.
|
|
.pipe($.if('*.html', cssslam.gulp())) // Minify CSS in HTML output.
|
|
.pipe($.if('*.js', uglifyJS())) // Minify JS in HTML output.
|
|
.pipe($.if('*.js', license())) // Add license to top.
|
|
.pipe(gulp.dest('static/elements'));
|
|
});
|
|
|
|
gulp.task('vulcanize', ['styles', 'vulcanize-lazy-elements'], () => {
|
|
return gulp.src([
|
|
'static/elements/metrics-imports.html',
|
|
'static/elements/features-imports.html',
|
|
'static/elements/admin-imports.html',
|
|
'static/elements/samples-imports.html',
|
|
])
|
|
.pipe($.vulcanize({
|
|
stripComments: true,
|
|
inlineScripts: true,
|
|
inlineCss: true
|
|
}))
|
|
.pipe($.rename({suffix: '.vulcanize'}))
|
|
.pipe($.crisper({scriptInHead: true})) // Separate HTML and JS. CSP friendly.
|
|
.pipe($.if('*.html', minifyHtml())) // Minify HTML output.
|
|
.pipe($.if('*.html', cssslam.gulp())) // Minify CSS in HTML output.
|
|
.pipe($.if('*.js', uglifyJS())) // Minify JS in HTML output.
|
|
.pipe($.if('*.js', license())) // Add license to top.
|
|
.pipe(gulp.dest('static/elements'));
|
|
});
|
|
|
|
// Clean generated files
|
|
gulp.task('clean', () => {
|
|
del([
|
|
'static/css/',
|
|
'static/dist',
|
|
'static/elements/*.vulcanize.{html,js}',
|
|
'static/js/**/*.es6.min.js'
|
|
], {dot: true});
|
|
|
|
});
|
|
|
|
// Build production files, the default task
|
|
gulp.task('default', ['clean'], cb =>
|
|
runSequence(
|
|
'styles',
|
|
'lint',
|
|
'vulcanize',
|
|
'js',
|
|
'generate-service-worker',
|
|
cb
|
|
)
|
|
);
|
|
|
|
// Generate a service worker file that will provide offline functionality for
|
|
// local resources.
|
|
gulp.task('generate-service-worker', () => {
|
|
const staticDir = 'static';
|
|
const distDir = path.join(staticDir, 'dist');
|
|
const filepath = path.join(distDir, 'service-worker.js');
|
|
|
|
return swPrecache.write(filepath, {
|
|
cacheId: 'chromestatus',
|
|
verbose: true,
|
|
logger: $.util.log,
|
|
staticFileGlobs: [
|
|
// Images
|
|
`${staticDir}/img/{browsers-logos.png,*.svg,crstatus_128.png,github-white.png}`,
|
|
`${staticDir}/elements/openinnew.svg`,
|
|
// Scripts
|
|
`${staticDir}/bower_components/webcomponentsjs/webcomponents-lite.min.js`,
|
|
`${staticDir}/js/**/!(*.es6).js`, // Don't include unminimized/untranspiled js.
|
|
// Styles. All styles are inline into pages or vulcanized bundles.
|
|
// Polymer imports
|
|
// NOTE: The admin imports are intentionally excluded, as the admin pages
|
|
// only work online
|
|
`${staticDir}/elements/paper-menu-button.vulcanize.*`,
|
|
`${staticDir}/elements/chromedash-legend.vulcanize.*`,
|
|
`${staticDir}/elements/metrics-imports.vulcanize.*`,
|
|
`${staticDir}/elements/features-imports.vulcanize.*`,
|
|
`${staticDir}/elements/samples-imports.vulcanize.*`,
|
|
],
|
|
runtimeCaching: [{ // Server-side generated content
|
|
// The features page, which optionally has a trailing slash or a
|
|
// feature id. For example:
|
|
// - /features
|
|
// - /features/
|
|
// - /features/<numeric feature id>
|
|
// This overly-specific regex is required to avoid matching other
|
|
// static content (i.e. /static/css/features/features.css)
|
|
urlPattern: /\/features(\/(\w+)?)?$/,
|
|
handler: 'fastest',
|
|
options: {
|
|
cache: {
|
|
maxEntries: 10,
|
|
name: 'features-cache'
|
|
}
|
|
}
|
|
}, {
|
|
// The metrics pages (optionally with a trailing slash)
|
|
// - /metrics/css/animated
|
|
// - /metrics/css/timeline/animated
|
|
// - /metrics/css/popularity
|
|
// - /metrics/css/timeline/popularity
|
|
// - /metrics/feature/popularity
|
|
// - /metrics/feature/timeline/popularity
|
|
urlPattern: /\/metrics\/(css|feature)\/(timeline\/)?(animated|popularity)(\/)?$/,
|
|
handler: 'fastest',
|
|
options: {
|
|
cache: {
|
|
maxEntries: 10,
|
|
name: 'metrics-cache'
|
|
}
|
|
}
|
|
}, {
|
|
// The samples page (optionally with a trailing slash)
|
|
urlPattern: /\/samples(\/)?$/,
|
|
handler: 'fastest',
|
|
options: {
|
|
cache: {
|
|
maxEntries: 10,
|
|
name: 'samples-cache'
|
|
}
|
|
}
|
|
}, {
|
|
// For dynamic data (json), use "fastest" so liefi scenarios are fast.
|
|
// "fastest" also makes a network request to update the cached copy.
|
|
// The worst case is that the user with an active SW gets stale content
|
|
// and never refreshes the page.
|
|
// TODO: use sw-toolbox notifyOnCacheUpdate when it's ready
|
|
// https://github.com/GoogleChrome/sw-toolbox/pull/174/
|
|
urlPattern: /\/data\//,
|
|
handler: 'fastest'
|
|
}, {
|
|
urlPattern: /\/features.json$/,
|
|
handler: 'fastest'
|
|
}, {
|
|
urlPattern: /\/samples.json$/,
|
|
handler: 'fastest'
|
|
}, {
|
|
urlPattern: /\/omaha_data$/,
|
|
handler: 'fastest'
|
|
}]
|
|
});
|
|
});
|
|
|
|
// 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); }
|