martinmicunda/employee-scheduling-ui

View on GitHub
gulp/tasks/build.js

Summary

Maintainability
A
0 mins
Test Coverage
/**
 * @author    Martin Micunda {@link http://martinmicunda.com}
 * @copyright Copyright (c) 2015, Martin Micunda
 * @license   GPL-3.0
 */
'use strict';

import del from 'del';
import rev from 'gulp-rev';
import gulp from 'gulp';
import util from 'gulp-util';
import size from 'gulp-size';
import uglify from 'gulp-uglify';
import gulpif from 'gulp-if';
import usemin from 'gulp-usemin';
import inject from 'gulp-inject';
import header from 'gulp-header';
import cdnizer from 'gulp-cdnizer';
import bytediff from 'gulp-bytediff';
import minifyCss from 'gulp-minify-css';
import minifyHtml from 'gulp-minify-html';
import runSequence from 'run-sequence';
import path from '../paths';
import {BANNER, CDN_URL, GH_PAGES_BASE_URL} from '../const';

//=============================================
//            UTILS FUNCTIONS
//=============================================
const LOG = util.log;
const COLORS = util.colors;
const HAS_CDN = !!util.env.cdn;
const SET_GH_PAGES_BASE_URL = !!util.env.ghpages;
const BASE_URL = SET_GH_PAGES_BASE_URL ? GH_PAGES_BASE_URL : '/';

/**
 * Format a number as a percentage
 * @param  {Number} num       Number to format as a percent
 * @param  {Number} precision Precision of the decimal
 * @return {String}           Formatted perentage
 */
function formatPercent(num, precision){
    return (num * 100).toFixed(precision);
}

/**
 * Formatter for bytediff to display the size changes after processing
 * @param  {Object} data - byte data
 * @return {String}      Difference in bytes, formatted
 */
function bytediffFormatter(data) {
    const difference = (data.savings > 0) ? ' smaller.' : ' larger.';
    return COLORS.yellow(data.fileName + ' went from ' +
        (data.startSize / 1000).toFixed(2) + ' kB to ' +
        (data.endSize / 1000).toFixed(2) + ' kB and is ' +
        formatPercent(1 - data.percent, 2) + '%' + difference);
}

//=============================================
//                  TASKS
//=============================================
/**
 * The 'clean' task delete 'build' and '.tmp' directories.
 *
 * @param {Function} done - callback when complete
 */
gulp.task('clean', (cb) => {
    const files = [].concat(path.build.basePath, path.tmp.basePath);
    LOG('Cleaning: ' + COLORS.blue(files));

    return del(files, cb);
});

/**
 * The 'copy' task just copies files from A to B. We use it here
 * to copy our files that haven't been copied by other tasks
 * e.g. (favicon, etc.) into the `build/dist` directory.
 *
 * @return {Stream}
 */
gulp.task('extras', () => {
    return gulp.src([path.app.basePath + '*.{ico,png,txt}'])
        .pipe(gulp.dest(path.build.dist.basePath));
});

/**
 * The 'copy' task just copies files from A to B. We use it here
 * to copy our files that haven't been copied by other tasks
 * e.g. (reports, etc.) into the `build/test-reports` directory.
 *
 * @return {Stream}
 */
gulp.task('extras-reports', () => {
    return gulp.src([path.test.testReports.basePath + '**/*'])
        .pipe(gulp.dest(path.build.testReports));
});

/**
 * Create JS production bundle.
 *
 * @param {Function} done - callback when complete
 */
gulp.task('bundle', ['jshint'], (cb) => {
    const ENV = !!util.env.env ? util.env.env : 'DEV';
    const Builder = require('systemjs-builder');
    const builder = new Builder();
    const inputPath = 'src/app/app';
    const outputFile = `${path.tmp.scripts}build.js`;
    const outputOptions = {sourceMaps: true, config: {sourceRoot: path.tmp.scripts}, conditions: { 'src/app/core/config/env.conditions.js|mock.js': ENV.toLowerCase() === 'test', 'src/app/core/config/env.conditions.js|environment': ENV.toLowerCase()} };

    builder.loadConfig(`${path.root}/jspm.conf.js`)
        .then(() => {
            builder.buildStatic(inputPath, outputFile, outputOptions)
                .then(() => cb())
                .catch((ex) => cb(new Error(ex)));
        });
});

/**
 * The 'compile' task compile all js, css and html files.
 *
 * 1. it inject bundle into `index.html`
 * 2. css      - replace local path with CDN url, minify, add revision number, add banner header
 *    js       - annotates the sources before minifying, minify, add revision number, add banner header
 *    html     - replace local path with CDN url, minify
 *
 * @return {Stream}
 */
gulp.task('compile', ['htmlhint', 'sass', 'bundle'], () => {

    return gulp.src(path.app.html)
        .pipe(inject(gulp.src(path.tmp.scripts + 'build.js', {read: false}), {
            starttag: '<!-- inject:build:js -->',
            ignorePath: [path.app.basePath]
        }))
        .pipe(inject(gulp.src('.'), {
            starttag: '<!-- inject:baseUrl -->',
            transform: () => `<base href="${BASE_URL}">`
        }))
        .pipe(usemin({
            css:        [
                gulpif(HAS_CDN, cdnizer({defaultCDNBase: CDN_URL, relativeRoot: 'styles', files: ['**/*.{gif,png,jpg,jpeg}']})),
                bytediff.start(),
                minifyCss({keepSpecialComments: 0}),
                bytediff.stop(bytediffFormatter),
                rev(),
                header(BANNER)
            ],
            /*jshint camelcase: false */
            js:         [
                gulpif(HAS_CDN, cdnizer({defaultCDNBase: CDN_URL, relativeRoot: '/', files: ['**/*.{gif,png,jpg,jpeg}']})),
                bytediff.start(),
                uglify(),
                bytediff.stop(bytediffFormatter),
                rev(),
                header(BANNER)
            ],
            html:       [
                gulpif(HAS_CDN, cdnizer({defaultCDNBase: CDN_URL, files: ['**/*.{js,css,gif,png,jpg,jpeg}']})),
                bytediff.start(),
                minifyHtml({empty:true}),
                bytediff.stop(bytediffFormatter)
            ]
        }))
        .pipe(gulp.dest(path.build.dist.basePath))
        .pipe(size({title: 'compile', showFiles: true}));
});

/**
 * The 'build' task gets app ready for deployment by processing files
 * and put them into directory ready for production.
 *
 * @param {Function} done - callback when complete
 */
gulp.task('build', (cb) => {
    runSequence(
        ['clean'],
        ['compile', 'extras', 'extras-reports', 'images', 'fonts'],
        cb
    );
});