Поиск по этому блогу

понедельник, 20 июня 2016 г.

Копипаст трех gulpfile.js и ссылки на всякую всячину из папок репозиториев Google

Просмтривал корень репозитория material-design-lite, узнал, что Babel is a JavaScript compiler, Drone is a hosted continuous integration service. В комментариях к статье на хабре Google Web Starter Kit: конструктор мобильных сайтов нашел три ссылки на сервисы building high-quality mobile apps, которые решил считать альтернативами...
Потом решил, что надо бы добавить сюда все ссылки на gulpfile.js из web-starter-kit, WebFundamentals и iliakan/gulp-screencast (от Ильи Кантора)

developers.google.com/ github WebFundamentals
material-design-lite/gulpfile.babel.js
Babel is a JavaScript compiler Create a .babelrc file in your project (or use your package.json)
Drone is a hosted continuous integration service. It enables you to conveniently set up projects to automatically build, test, and deploy as you make changes to your code.

Web Starter Kit docs is an opinionated boilerplate for web development. Tools for building a great experience across many devices and performance oriented. Helping you to stay productive following the best practices outlined in Google's Web Fundamentals. A solid starting point for both professionals and newcomers to the industry
web-starter-kit Deploy to Google App Engine Google App Engine lets you build and run applications on Google’s infrastructure. App Engine applications are easy to create, easy to maintain, and easy to scale as your traffic and data storage needs change.
Gulp docs web-starter-kitDifference Between serve & serve:dist There are many commands available to help you build and test sites. Here are a few highlights to get started with
Разработка → Google Web Starter Kit: конструктор мобильных сайтов Да, выглядит как-то не очень. Onsen.UI, например, выглядит намного более «нативнее»

onsen.ioHTML5 Hybrid Mobile App Framework and UI Components for PhoneGap & Cordova.
Start building with Ionic! These three simple steps will have you building high-quality mobile apps in minutes. For a more in-depth overview, watch our Crash Course video, or take our free online Ionic and Angular course, Appcamp.
ratchetBuild mobile apps with simple HTML‚ CSS‚ and JS components.

google / WebFundamentals
Web Fundamentals is a technical documentation center for multi-device web development. Our goal is to build a resource for modern web developers that’s as curated and thorough as developer.android.com or iOS Dev Center.

Далее 4 главные ссылки, а ниже именно в таком порядке копипаст трех галп-файлов.

iliakan/gulp-screencast Код к скринкасту по Gulp (И. Кантор)

Из дистрибутива MDL material-design-lite/gulpfile.babel.js
web-starter-kit/gulpfile.babel.js
WebFundamentals/gulpfile.js Здесь в файле используется импорт файлов из папки

For V1 of MDL we are focused on the use-case of folks who are likely to need a few different components on their page and will want to include most of the MDL library. This means that support and docs around just plucking single components on their own is minimal.

That said, if you need to generate a build using just a single (or smaller number of) components, you will need to use Gulp with our Sass build. You can comment out material-design-lite.scss those components you don’t need in material-design-lite.scss, comment out the scripts you don’t need in the Gulpfile (gulpfile.babel.js) and then run gulp to create your build.

We have talked about offering up components in a more modular fashion but will be exploring this in the post V1 timeline.

Из дистрибутива MDL material-design-lite/gulpfile.babel.js

In [ ]:
/**
 *
 *  Material Design Lite
 *  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
 *
 */

 // jscs:disable jsDoc

'use strict';

// Include Gulp & Tools We'll Use
import fs from 'fs';
import path from 'path';
import mergeStream from 'merge-stream';
import del from 'del';
import vinylPaths from 'vinyl-paths';
import runSequence from 'run-sequence';
import browserSync from 'browser-sync';
import through from 'through2';
import swig from 'swig';
import gulp from 'gulp';
import closureCompiler from 'gulp-closure-compiler';
import gulpLoadPlugins from 'gulp-load-plugins';
import pkg from './package.json';

const $ = gulpLoadPlugins();
const reload = browserSync.reload;
const hostedLibsUrlPrefix = 'https://code.getmdl.io';
const templateArchivePrefix = 'mdl-template-';
const bucketProd = 'gs://www.getmdl.io';
const bucketStaging = 'gs://mdl-staging';
const bucketCode = 'gs://code.getmdl.io';
const banner = ['/**',
  ' * <%= pkg.name %> - <%= pkg.description %>',
  ' * @version v<%= pkg.version %>',
  ' * @license <%= pkg.license %>',
  ' * @copyright 2015 Google, Inc.',
  ' * @link https://github.com/google/material-design-lite',
  ' */',
  ''].join('\n');

let codeFiles = '';

const AUTOPREFIXER_BROWSERS = [
  'ie >= 11',
  'edge >= 20',
  'ff >= 44',
  'chrome >= 48',
  'safari >= 8',
  'opera >= 35',
  'ios >= 8'
];

const SOURCES = [
  'src/component.js',
  // Base components
  // 'src/button/button.js',
  'src/checkbox/checkbox.js',
  'src/icon-toggle/icon-toggle.js',
  'src/menu/menu.js',
  // 'src/progress/progress.js',
  'src/radio/radio.js',
  // 'src/slider/slider.js',
  // 'src/snackbar/snackbar.js',
  'src/spinner/spinner.js',
  'src/switch/switch.js'
  // 'src/tabs/tabs.js',
  // 'src/textfield/textfield.js',
  // 'src/tooltip/tooltip.js',
  // Complex components (which reuse base components)
  // 'src/layout/layout.js',
  // And finally, the ripples
  // 'src/ripple/ripple.js'
];

const COMPONENT_HEADER = `---
layout: component
bodyclass: component\n
include_prefix: ../../
---
`;

const DEMO_HEADER = `---
layout: demo
bodyclass: demo\n
include_prefix: ../../
---
`;

// ***** Development tasks ****** //

// Lint JS sources.
gulp.task('lint:sources', () => {
  return gulp.src(['utils/export.js'].concat(SOURCES))
    .pipe($.eslint())
    .pipe($.eslint.format())
    .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
});

// Lint auxiliary JS.
gulp.task('lint:aux', () => {
  return gulp.src(['gulpfile.babel.js'])
    .pipe($.eslint({
      env: {
        browser: false
      }
    }))
    .pipe($.eslint.format())
    .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
});

// Lint JavaScript
gulp.task('lint', ['lint:sources', 'lint:aux'], () => {});

// ***** Production build tasks ****** //

/**
 * Optimize Images
 *
 * @todo: Update image paths in final CSS to match root/images
 */
gulp.task('images', () => {
  return gulp.src('src/**/*.{svg,png,jpg}')
    .pipe($.flatten())
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'images'}));
});

// Compile and Automatically Prefix Stylesheets (dev)
gulp.task('styles:dev', () => {
  return gulp.src('src/**/*.scss')
    .pipe($.sass({
      precision: 10,
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.cssInlineImages({
      webRoot: 'src'
    }))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp/styles'))
    .pipe($.size({title: 'styles'}));
});

// Compile and Automatically Prefix Stylesheet Templates (production)
gulp.task('styletemplates', () => {
  // For best performance, don't add Sass partials to `gulp.src`
  return gulp.src('src/template.scss')
    // Generate Source Maps
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      precision: 10,
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.cssInlineImages({webRoot: 'src'}))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp'))
    // Concatenate Styles
    .pipe($.concat('material.css.template'))
    .pipe(gulp.dest('dist'))
    // Minify Styles
    .pipe($.if('*.css.template', $.csso()))
    .pipe($.concat('material.min.css.template'))
    .pipe($.header(banner, {pkg}))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'styles'}));
});

// Compile and Automatically Prefix Stylesheets (production)
gulp.task('styles', () => {
  // For best performance, don't add Sass partials to `gulp.src`
  return gulp.src('src/material-design-lite.scss')
    // Generate Source Maps
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      precision: 10,
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.cssInlineImages({webRoot: 'src'}))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp'))
    // Concatenate Styles
    .pipe($.concat('material.css'))
    .pipe($.header(banner, {pkg}))
    .pipe(gulp.dest('dist'))
    // Minify Styles
    .pipe($.if('*.css', $.csso()))
    .pipe($.concat('material.min.css'))
    .pipe($.header(banner, {pkg}))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'styles'}));
});

// Only generate CSS styles for the MDL grid
gulp.task('styles-grid', () => {
  return gulp.src('src/material-design-lite-grid.scss')
    .pipe($.sass({
      precision: 10,
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp'))
    // Concatenate Styles
    .pipe($.concat('material-grid.css'))
    .pipe($.header(banner, {pkg}))
    .pipe(gulp.dest('dist'))
    // Minify Styles
    .pipe($.if('*.css', $.csso()))
    .pipe($.concat('material-grid.min.css'))
    .pipe($.header(banner, {pkg}))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'styles-grid'}));
});

// Concatenate And Minify JavaScript
gulp.task('scripts', ['lint:sources'], () => {
  return gulp.src(['utils/export.js'].concat(SOURCES))
    .pipe($.sourcemaps.init())
    .pipe(closureCompiler({
      compilerPath: 'node_modules/google-closure-compiler/compiler.jar',
      fileName: 'material.min.js',
      compilerFlags: {
        /* eslint-disable camelcase */
        compilation_level: 'ADVANCED_OPTIMIZATIONS',
        language_in: 'ECMASCRIPT6_STRICT',
        language_out: 'ECMASCRIPT5_STRICT',
        warning_level: 'VERBOSE',
        generate_exports: true,
        export_local_property_definitions: true
        // eslint-enable camelcase
      }
    }))
    .pipe($.header(banner, {pkg}))
    .pipe($.concat('material.min.js'))
    // Write Source Maps
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'scripts'}));
});

// Clean Output Directory
gulp.task('clean', () => del(['dist', '.publish']));

// Copy package manger and LICENSE files to dist
gulp.task('metadata', () => {
  return gulp.src([
    'package.json',
    'bower.json',
    'LICENSE'
  ])
  .pipe(gulp.dest('dist'));
});

// Build Production Files, the Default Task
gulp.task('default', ['clean'], cb => {
  runSequence(
    ['styles', 'styles-grid'],
    ['scripts'],
    ['mocha'],
    cb);
});

// Build production files and microsite
gulp.task('all', ['clean'], cb => {
  runSequence(
    ['lint:aux'],
    ['styletemplates'],
    ['styles-grid', 'styles:gen'],
    ['scripts'],
    ['mocha'],
    ['assets', 'pages',
     'templates', 'images', 'metadata'],
    ['zip'],
    cb);
});

// ***** Testing tasks ***** //

gulp.task('mocha', ['styles'], () => {
  return gulp.src('test/index.html')
    .pipe($.mochaPhantomjs({reporter: 'tap'}));
});

gulp.task('test', [
  'lint',
  'mocha'
]);

gulp.task('test:visual', () => {
  browserSync({
    notify: false,
    server: '.',
    startPath: 'test/visual/index.html'
  });

  gulp.watch('test/visual/**', reload);
});

// ***** Landing page tasks ***** //

/**
 * Site metadata for use with templates.
 * @type {Object}
 */
const site = {};

/**
 * Generates an HTML file based on a template and file metadata.
 *
 * @return {function} function that applies a template
 */
function applyTemplate() {
  return through.obj((file, enc, cb) => {
    const data = {
      site,
      page: file.page,
      content: file.contents.toString()
    };

    const templateFile = path.join(
        __dirname, 'docs', '_templates', `${file.page.layout}.html`);
    const tpl = swig.compileFile(templateFile, {cache: false});

    file.contents = new Buffer(tpl(data));
    cb(null, file);
  });
}

/**
 * Generates an index.html file for each README in MDL/src directory.
 */
gulp.task('components', ['demos'], () => {
  return gulp.src('src/**/README.md', {base: 'src'})
    // Add basic front matter.
    .pipe($.header(COMPONENT_HEADER))
    .pipe($.frontMatter({
      property: 'page',
      remove: true
    }))
    .pipe($.marked())
    .pipe((() => {
      return through.obj((file, enc, cb) => {
        file.page.component = file.relative.split('/')[0];
        cb(null, file);
      });
    })())
    .pipe(applyTemplate())
    .pipe($.rename(path => {
      path.basename = 'index';
    }))
    .pipe(gulp.dest('dist/components'));
});

/**
 * Copies demo files from MDL/src directory.
 *
 * @return {Object} The set of demo files.
 */
gulp.task('demoresources', () => {
  return gulp.src([
    'src/**/demos.css',
    'src/**/demo.css',
    'src/**/demo.js'
  ], {base: 'src'})
  .pipe($.if('*.scss', $.sass({
    precision: 10,
    onError: console.error.bind(console, 'Sass error:')
  })))
  .pipe($.cssInlineImages({webRoot: 'src'}))
  .pipe($.if('*.css', $.autoprefixer(AUTOPREFIXER_BROWSERS)))
  .pipe(gulp.dest('dist/components'));
});

/**
 * Generates demo files for testing made of all the snippets and the demo file
 * put together.
 */
gulp.task('demos', ['demoresources'], () => {
  /**
   * Retrieves the list of component folders.
   *
   * @return {Object} The list of component folers.
   */
  function getComponentFolders() {
    return fs.readdirSync('src')
      .filter(file => fs.statSync(path.join('src', file)).isDirectory());
  }

  const tasks = getComponentFolders().map(component => {
    return gulp.src([
      path.join('src', component, 'snippets', '*.html'),
      path.join('src', component, 'demo.html')
    ])
    .pipe($.concat('/demo.html'))
    // Add basic front matter.
    .pipe($.header(DEMO_HEADER))
    .pipe($.frontMatter({
      property: 'page',
      remove: true
    }))
    .pipe($.marked())
    .pipe((() => {
      return through.obj((file, enc, cb) => {
        file.page.component = component;
        cb(null, file);
      });
    })())
    .pipe(applyTemplate())
    .pipe(gulp.dest(path.join('dist', 'components', component)));
  });

  return mergeStream(tasks);
});

/**
 * Generates an HTML file for each md file in _pages directory.
 */
gulp.task('pages', ['components'], () => {
  return gulp.src('docs/_pages/*.md')
    .pipe($.frontMatter({
      property: 'page',
      remove: true
    }))
    .pipe($.marked())
    .pipe(applyTemplate())
    .pipe($.replace('$$version$$', pkg.version))
    .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
    .pipe($.replace('$$template_archive_prefix$$', templateArchivePrefix))
    /* Replacing code blocks class name to match Prism's. */
    .pipe($.replace('class="lang-', 'class="language-'))
    /* Translate html code blocks to "markup" because that's what Prism uses. */
    .pipe($.replace('class="language-html', 'class="language-markup'))
    .pipe($.rename(path => {
      if (path.basename !== 'index') {
        path.dirname = path.basename;
        path.basename = 'index';
      }
    }))
    .pipe(gulp.dest('dist'));
});

/**
 * Copies assets from MDL and _assets directory.
 */
gulp.task('assets', () => {
  return gulp.src([
    'docs/_assets/**/*',
    'node_modules/prismjs/prism.js',
    'node_modules/prismjs/components/prism-markup.min.js',
    'node_modules/prismjs/components/prism-javascript.min.js',
    'node_modules/prismjs/components/prism-css.min.js',
    'node_modules/prismjs/components/prism-bash.min.js',
    'node_modules/prismjs/themes/prism.css'
  ])
  .pipe($.if(/\.js/i, $.replace('$$version$$', pkg.version)))
  .pipe($.if(/\.js/i, $.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix)))
  .pipe($.if(/\.(svg|jpg|png)$/i, $.imagemin({
    progressive: true,
    interlaced: true
  })))
  .pipe($.if(/\.css/i, $.autoprefixer(AUTOPREFIXER_BROWSERS)))
  .pipe($.if(/\.css/i, $.csso()))
  .pipe($.if(/\.js/i, $.uglify({
    preserveComments: 'some',
    sourceRoot: '.',
    sourceMapIncludeSources: true
  })))
  .pipe(gulp.dest('dist/assets'));
});

/**
 * Defines the list of resources to watch for changes.
 */
function watch() {
  gulp.watch(['src/**/*.js', '!src/**/README.md'],
    ['scripts', 'demos', 'components', reload]);
  gulp.watch(['src/**/*.{scss,css}'],
    ['styles', 'styles-grid', 'styletemplates', reload]);
  gulp.watch(['src/**/*.html'], ['pages', reload]);
  gulp.watch(['src/**/*.{svg,png,jpg}'], ['images', reload]);
  gulp.watch(['src/**/README.md'], ['pages', reload]);
  gulp.watch(['templates/**/*'], ['templates', reload]);
  gulp.watch(['docs/**/*'], ['pages', 'assets', reload]);
  gulp.watch(['package.json', 'bower.json', 'LICENSE'], ['metadata']);
}

/**
 * Serves the landing page from "out" directory.
 */
gulp.task('serve:browsersync', () => {
  browserSync({
    notify: false,
    server: {
      baseDir: ['dist']
    }
  });

  watch();
});

gulp.task('serve', () => {
  $.connect.server({
    root: 'dist',
    port: 5000,
    livereload: true
  });

  watch();

  gulp.src('dist/index.html')
    .pipe($.open({uri: 'http://localhost:5000'}));
});

// Generate release archive containing just JS, CSS, Source Map deps
gulp.task('zip:mdl', () => {
  return gulp.src([
    'dist/material?(.min)@(.js|.css)?(.map)',
    'LICENSE',
    'bower.json',
    'package.json'
  ])
  .pipe($.zip('mdl.zip'))
  .pipe(gulp.dest('dist'));
});

/**
 * Returns the list of children directories inside the given directory.
 * @param {string} dir the parent directory
 * @return {Array<string>} list of child directories
 */
function getSubDirectories(dir) {
  return fs.readdirSync(dir)
    .filter(file => fs.statSync(path.join(dir, file)).isDirectory());
}

// Generate release archives containing the templates and assets for templates.
gulp.task('zip:templates', () => {
  const templates = getSubDirectories('dist/templates');

  // Generate a zip file for each template.
  const generateZips = templates.map(template => {
    return gulp.src([
      `dist/templates/${template}/**/*.*`,
      'LICENSE'
    ])
    .pipe($.rename(path => {
      path.dirname = path.dirname.replace(`dist/templates/${template}`, '');
    }))
    .pipe($.zip(`${templateArchivePrefix}${template}.zip`))
    .pipe(gulp.dest('dist'));
  });

  return mergeStream(generateZips);
});

gulp.task('zip', [
  'zip:templates',
  'zip:mdl'
]);

gulp.task('genCodeFiles', () => {
  return gulp.src([
    'dist/material.*@(js|css)?(.map)',
    'dist/mdl.zip',
    `dist/${templateArchivePrefix}*.zip`
  ], {read: false})
  .pipe($.tap(file => {
    codeFiles += ` dist/${path.basename(file.path)}`;
  }));
});

// Push the latest version of code resources (CSS+JS) to Google Cloud Storage.
// Public-read objects in GCS are served by a Google provided and supported
// global, high performance caching/content delivery network (CDN) service.
// This task requires gsutil to be installed and configured.
// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
gulp.task('pushCodeFiles', () => {
  const dest = bucketCode;
  console.log(`Publishing ${pkg.version} to CDN (${dest})`);

  // Build cache control and gsutil cmd to copy
  // each object into a GCS bucket. The dest is a version specific path.
  // The gsutil -m option requests parallel copies.
  // The gsutil -h option is used to set metadata headers
  // (cache control, in this case).
  // Code files should NEVER be touched after uploading, therefore
  // 30 days caching is a safe value.
  const cacheControl = '-h "Cache-Control:public,max-age=2592000"';
  const gsutilCpCmd = 'gsutil -m cp -z js,css,map ';
  const gsutilCacheCmd = `gsutil -m setmeta -R ${cacheControl}`;

  // Upload the goodies to a separate GCS bucket with versioning.
  // Using a sep bucket avoids the risk of accidentally blowing away
  // old versions in the microsite bucket.
  return gulp.src('')
    .pipe($.shell([
      `${gsutilCpCmd}${codeFiles} ${dest}/${pkg.version}`,
      `${gsutilCacheCmd} ${dest}/${pkg.version}`
    ]));
});

gulp.task('publish:code', cb => {
  runSequence(
    ['zip:mdl', 'zip:templates'],
    'genCodeFiles',
    'pushCodeFiles',
    cb);
});

/**
 * Function to publish staging or prod version from local tree,
 * or to promote staging to prod, per passed arg.
 * @param {string} pubScope the scope to publish to.
 */
function mdlPublish(pubScope) {
  let cacheTtl = null;
  let src = null;
  let dest = null;

  if (pubScope === 'staging') {
    // Set staging specific vars here.
    cacheTtl = 0;
    src = 'dist/*';
    dest = bucketStaging;
  } else if (pubScope === 'prod') {
    // Set prod specific vars here.
    cacheTtl = 60;
    src = 'dist/*';
    dest = bucketProd;
  } else if (pubScope === 'promote') {
    // Set promote (essentially prod) specific vars here.
    cacheTtl = 60;
    src = `${bucketStaging}/*`;
    dest = bucketProd;
  }

  let infoMsg = `Publishing ${pubScope}/${pkg.version} to GCS (${dest})`;
  if (src) {
    infoMsg += ` from ${src}`;
  }
  console.log(infoMsg);

  // Build gsutil commands:
  // The gsutil -h option is used to set metadata headers.
  // The gsutil -m option requests parallel copies.
  // The gsutil -R option is used for recursive file copy.
  const cacheControl = `-h "Cache-Control:public,max-age=${cacheTtl}"`;
  const gsutilCacheCmd = `gsutil -m setmeta ${cacheControl} ${dest}/**`;
  const gsutilCpCmd = `gsutil -m cp -r -z html,css,js,svg ${src} ${dest}`;

  gulp.src('').pipe($.shell([gsutilCpCmd, gsutilCacheCmd]));
}

// Push the local build of the MDL microsite and release artifacts to the
// production Google Cloud Storage bucket for general serving to the web.
// Public-read objects in GCS are served by a Google provided and supported
// global, high performance caching/content delivery network (CDN) service.
// This task requires gsutil to be installed and configured.
// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
//
gulp.task('publish:prod', () => {
  mdlPublish('prod');
});

// Promote the staging version of the MDL microsite and release artifacts
// to the production Google Cloud Storage bucket for general serving.
// Public-read objects in GCS are served by a Google provided and supported
// global, high performance caching/content delivery network (CDN) service.
// This task requires gsutil to be installed and configured.
// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
//
gulp.task('publish:promote', () => {
  mdlPublish('promote');
});

// Push the staged version of the MDL microsite and release artifacts
// to a production Google Cloud Storage bucket for staging and pre-production testing.
//
// This task requires gsutil to be installed and configured.
// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
//
gulp.task('publish:staging', () => {
  mdlPublish('staging');
});

gulp.task('_release', () => {
  return gulp.src([
    'dist/material?(.min)@(.js|.css)?(.map)',
    'LICENSE',
    'README.md',
    'bower.json',
    'package.json',
    '.jscsrc',
    '.jshintrc',
    './sr?/**/*',
    'gulpfile.babel.js',
    './util?/**/*'
  ])
  .pipe(gulp.dest('_release'));
});

gulp.task('publish:release', ['_release'], () => {
  return gulp.src('_release')
    .pipe($.subtree({
      remote: 'origin',
      branch: 'release'
    }))
    .pipe(vinylPaths(del));
});

gulp.task('templates:styles', () => {
  return gulp.src('templates/**/*.css')
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe($.csso())
    .pipe(gulp.dest('dist/templates'));
});

gulp.task('templates:static', () => {
  return gulp.src('templates/**/*.html')
  .pipe($.replace('$$version$$', pkg.version))
  .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
  .pipe(gulp.dest('dist/templates'));
});

// This task can be used if you want to test the templates against locally
// built version of the MDL libraries.
gulp.task('templates:localtestingoverride', () => {
  return gulp.src('templates/**/*.html')
    .pipe($.replace('$$version$$', '.'))
    .pipe($.replace('$$hosted_libs_prefix$$', ''))
    .pipe(gulp.dest('dist/templates'));
});

gulp.task('templates:images', () => {
  return gulp.src('templates/*/images/**/*')
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('dist/templates'));
});

gulp.task('templates:fonts', () => {
  return gulp.src('templates/*/fonts/**/*')
    .pipe(gulp.dest('dist/templates/'));
});

gulp.task('templates', [
  'templates:static',
  'templates:images',
  'templates:fonts',
  'templates:styles'
]);

gulp.task('styles:gen', ['styles'], () => {
  const MaterialCustomizer = require('./docs/_assets/customizer.js');
  const templatePath =
      path.join(__dirname, 'dist', 'material.min.css.template');
  /**
   * @todo: This task needs refactoring once we turn MaterialCustomizer
   * into a proper Node module.
   */
  const mc = new MaterialCustomizer();
  mc.template = fs.readFileSync(templatePath).toString();

  let stream = gulp.src('');

  mc.paletteIndices.forEach(primary => {
    mc.paletteIndices.forEach(accent => {
      if (primary === accent) {
        return;
      }

      if (mc.forbiddenAccents.indexOf(accent) !== -1) {
        return;
      }

      const primaryName = primary.toLowerCase().replace(' ', '_');
      const accentName = accent.toLowerCase().replace(' ', '_');

      stream = stream.pipe($.file(
        `material.${primaryName}-${accentName}.min.css`,
        mc.processTemplate(primary, accent)
      ));
    });
  });

  stream.pipe(gulp.dest('dist'));
});
In [ ]:
####Из [web-starter-kit/gulpfile.babel.js](https://github.com/google/web-starter-kit/blob/master/gulpfile.babel.js)
In [ ]:
/**
 *
 *  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}',
      noAssets: true
    }))

    // 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', reload]);
  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); }
In [ ]:
'use strict';

var del = require('del');
var minimist = require('minimist');
var chalk = require('chalk');

var knownOptions = {
  string: ['lang', 'section'],
  default: {
    lang: null,
    section: null
  }
};

GLOBAL.WF = {
  gae: 'appengine-config',
  src: {
    content: 'src/content',
    jekyll: 'src/jekyll',
    jekyllConfigs: 'src/jekyll/_config',
    imgs: 'src/static/imgs',
    styles: 'src/static/styles',
    fonts: 'src/static/fonts',
    scripts: 'src/static/scripts',
    thirdParty: 'src/static/third_party'
  },
  build: {
    root: 'build',
    jekyll: 'build/langs',
    imgs: 'build/imgs',
    styles: 'build/styles',
    fonts: 'build/fonts',
    scripts: 'build/scripts'
  }
};
GLOBAL.WF.options = minimist(process.argv.slice(2), knownOptions);

console.log('');
console.log('---------------------------------');
console.log('');
if (GLOBAL.WF.options.lang === null) {
  console.log(chalk.dim('    Building all languages.'));
  console.log(chalk.white('    Add ') +
    chalk.magenta('--lang <Language Code>') +
    chalk.white(' to build a specific language.'));
} else {
  console.log(chalk.dim('    Building language: ') +
    chalk.white(GLOBAL.WF.options.lang));
}
console.log('');
if (GLOBAL.WF.options.section === null) {
  console.log(chalk.dim('    Building all sections.'));
  console.log(chalk.white('    Add ') +
    chalk.magenta('--section <Section Folder Name>') +
    chalk.white(' to build a specific section.'));
} else {
  console.log(chalk.dim('    Building section: ') +
    chalk.white(GLOBAL.WF.options.section));
}
console.log('');
console.log('---------------------------------');
console.log('');

var gulp = require('gulp');
var runSequence = require('run-sequence');
var requireDir = require('require-dir');

requireDir('./gulp-tasks');

gulp.task('clean', del.bind(null,
  [
    GLOBAL.WF.build.root
  ], {dot: true}));

gulp.task('develop', function(cb) {
  runSequence(
    'clean',
    [
      'generate-dev-css',
      'cp-images',
      'cp-fonts',
      'cp-scripts',
    ],
    'compile-jekyll:localhost',
    'showcase',
    'start-gae-dev-server',
    'dev-watch-tasks',
    cb);
});

gulp.task('develop:prod', function(cb) {
  runSequence(
    'clean',
    'tests',
    [
      'generate-prod-css',
      'minify-images',
      'cp-fonts',
      'cp-scripts',
    ],
    'compile-jekyll:localhost',
    [
      'html',
      'minify-images:content'
    ],
    'showcase',
    'start-gae-dev-server',
    'prod-watch-tasks',
    cb);
});

gulp.task('build:staging', function(cb) {
  runSequence(
    'clean',
    'tests',
    [
      'generate-prod-css',
      'minify-images',
      'cp-fonts',
      'cp-scripts',
      'copy-appengine-config'
    ],
    'compile-jekyll:staging',
    [
      'html',
      'minify-images:content'
    ],
    'showcase',
    cb);
});

gulp.task('build', function(cb) {
  runSequence(
    'clean',
    'tests',
    [
      'generate-prod-css',
      'minify-images',
      'cp-fonts',
      'copy-appengine-config'
    ],
    'compile-jekyll:devsite',
    [
      'html',
      'minify-images:content'
    ],
    'showcase',
    cb);
});

/**
 * By default we'll kick of the development
 * build of WF
 **/
gulp.task('default', ['develop']);


Посты чуть ниже также могут вас заинтересовать

Комментариев нет: