Skip to content

Instantly share code, notes, and snippets.

@romamaslennikov
Last active January 2, 2017 06:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romamaslennikov/1ab12e2772ceea9cd5a154bf6c70f1de to your computer and use it in GitHub Desktop.
Save romamaslennikov/1ab12e2772ceea9cd5a154bf6c70f1de to your computer and use it in GitHub Desktop.
'use strict';
let config = {
apiProxy: process.env.PROXY || 'http://0.0.0.0:3002'
};
//=============================================
// DEPENDENCIES
//=============================================
/**
* Load required dependencies.
*/
const del = require('del');
const fs = require('fs');
const gulp = require('gulp');
const send = require('send');
const yaml = require('js-yaml');
const argv = require('yargs').argv;
const runSequence = require('run-sequence');
const browserSync = require('browser-sync');
const modRewrite = require('connect-modrewrite');
const proxyMiddleware = require('http-proxy-middleware');
/**
* Load Gulp plugins listed in 'package.json' and attaches them to the `$` variable.
*/
const $ = (require('gulp-load-plugins'))();
/**
* Declare variables that are use in gulpfile.js
*/
let log = $.util.log;
let envArgv = $.util.env;
let ENV = envArgv.env ? envArgv.env : 'development';
let COLORS = $.util.colors;
//=============================================
// UTILS FUNCTIONS
//=============================================
let notifyOnError = function() {
return $.notify.onError({
message: 'Error: <%= error.message %>',
sound: true
});
};
let formatPercent = (num, precision) => {
return (num * 100).toFixed(precision);
};
let bytediffFormatter = (data) => {
var difference, ref;
difference = (ref = data.savings > 0) != null ? ref : {
' 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");
};
let startBrowserSync = (baseDir, files, browser) => {
browser = !browser ? 'default' : browser;
files = !files ? 'default' : files;
return browserSync({
files: files,
port: argv.port || process.env.PORT || 3005,
notify: false,
open: false,
server: {
baseDir: baseDir
},
middleware: [
modRewrite([
'^(/)$ /public.html ',
'^(/admin-panel/.*|/admin) /private.html ',
'^(/search) /public.html ',
'^(/wishlist) /public.html ',
'^(/contacts) /public.html ',
'^(/sell-your-watch) /public.html ',
'^(/product/.*) /public.html ',
'^(/news/.*) /public.html ',
'^(/news) /public.html ']),
proxyMiddleware([
'/data/**',
'/api/**'
], {
target: argv.proxy || config.apiProxy,
changeOrigin: true
}),
(req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', "http://" + req.headers.host);
return next();
}
],
browser: browser
});
};
//=============================================
// DECLARE PATHS
//=============================================
let paths = {
gulpfile: 'gulpfile.js',
app: {
basePath: 'app/',
stylesMain: 'app/css/main.scss',
styles: {
"public": 'app/css/public/**/*.*css',
"private": 'app/css/private/**/*.*css'
},
fonts: ['app/fonts/**/*.{eot,svg,ttf,woff,woff2}', 'jspm_packages/**/*.{eot,svg,ttf,woff,woff2}'],
images: 'app/images/**/*.{png,gif,jpg,jpeg,svg,ico}',
scripts: ['app/scripts/**/*.js', '!app/scripts/**/*.spec.js'],
scriptsDir: 'app/scripts/',
html: ['app/scripts/**/*.html', 'app/index.html'],
publicHtml: 'app/public.html',
privateHtml: 'app/private.html',
configSocialName: 'app_secret_config.yml',
configSocialNameJson: 'app_secret_config.json',
configSocial: 'config/app_secret_config.yml',
configJsonName: 'app.config.json',
configJson: 'app/scripts/app.config.json'
},
tmp: {
basePath: '.tmp/',
styles: {
vendor: '.tmp/css/',
"public": '.tmp/css/public/',
"private": '.tmp/css/private/'
},
scripts: {
"public": '.tmp/scripts/public/',
"private": '.tmp/scripts/private/'
}
},
build: {
dist: {
basePath: 'build/',
"public": {
basePath: 'build/public/',
fonts: 'build/public/fonts/',
images: 'build/public/images/',
styles: 'build/public/styles/',
scripts: 'build/public/scripts/'
},
"private": {
basePath: 'build/private/',
fonts: 'build/private/fonts/',
images: 'build/private/images/',
styles: 'build/private/styles/',
scripts: 'build/private/scripts/'
}
},
docs: 'build/docs/'
}
};
//=============================================
// HELPER
//=============================================
/**
* Add the ability to provide help text to custom gulp tasks. Usage: `gulp help`
*/
$.help(gulp);
//=============================================
// SUB TASKS
//=============================================
/**
* The 'clean' task delete 'build' and '.tmp' directories.
*/
gulp.task('clean', 'Delete \'build\' and \'.tmp\' directories', (cb) => {
var files;
files = [].concat(paths.build.dist.basePath, paths.tmp.basePath);
log('Cleaning: ' + COLORS.blue(files));
return del(files, cb);
});
gulp.task('config', 'setup config variables', () => {
var appConfig, fileName;
fileName = paths.app.configJson;
appConfig = {
env: argv.env || 'development'
};
return fs.writeFileSync(fileName, JSON.stringify(appConfig));
});
/**
* The 'jshint' task defines the rules of our hinter as well as which files
* we should check. It helps to detect errors and potential problems in our
* JavaScript code.
*/
gulp.task('jshint', 'Hint JavaScripts files', () => {
return gulp.src(paths.app.scripts)
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
.pipe($.jshint.reporter('fail'))
.on('error', notifyOnError());
});
/**
* Compile SASS files into the main.css.
*/
gulp.task('styles:vendor', 'Compile vendor styles into the vendor.css', () => {
return gulp.src([
'jspm_packages/github/twbs/bootstrap@3.3.5/css/bootstrap.min.css',
'jspm_packages/github/twbs/bootstrap@3.3.5/css/bootstrap-theme.min.css',
'jspm_packages/github/select2/select2@3.4.5/select2.css',
'jspm_packages/github/angular-ui/ui-select@0.13.1/dist/select.min.css',
'jspm_packages/github/tameraydin/ngToast@1.5.4/dist/ngToast.min.css',
'jspm_packages/github/tameraydin/ngToast@1.5.4/dist/ngToast-animations.min.css',
'jspm_packages/github/components/jqueryui@1.11.4/themes/base/datepicker.css',
'jspm_packages/github/components/jqueryui@1.11.4/themes/base/theme.css',
'jspm_packages/github/daneden/animate.css@3.3.1/animate.min.css',
'jspm_packages/npm/font-awesome@4.4.0/css/font-awesome.min.css',
'jspm_packages/github/summernote/summernote@0.6.16/summernote.css'])
.pipe($.sass({
outputStyle: 'compressed',
errLogToConsole: true
}))
.on('error', notifyOnError())
.pipe($.concat('vendor.css'))
.pipe(gulp.dest(paths.tmp.styles.vendor));
});
gulp.task('styles-public:custom', 'Compile sass files into the custom.css', () => {
var errLogToConsole;
return gulp.src(paths.app.styles["public"])
.pipe($.changed(paths.tmp.styles["public"], {
extension: '.*ss'
}))
.pipe($.sourcemaps.init()).pipe($.sass({
outputStyle: 'compressed',
errLogToConsole: true
}))
.on('error', notifyOnError())
.pipe($.autoprefixer('last 2 version'))
.pipe($.concat('custom.css'))
.pipe($.sourcemaps.write('../maps'))
.pipe(gulp.dest(paths.tmp.styles["public"]));
});
gulp.task('styles-private:custom', 'Compile sass files into the custom.css', () => {
var errLogToConsole;
errLogToConsole = true;
return gulp.src(paths.app.styles["private"])
.pipe($.changed(paths.tmp.styles["private"], {
extension: '.*ss'
}))
.pipe($.sourcemaps.init())
.pipe($.sass({
outputStyle: 'compressed',
errLogToConsole: errLogToConsole
}))
.on('error', notifyOnError())
.pipe($.autoprefixer('last 2 version'))
.pipe($.concat('custom.css'))
.pipe($.sourcemaps.write('../maps'))
.pipe(gulp.dest(paths.tmp.styles["private"]));
});
gulp.task('styles-public:concat', 'Concat all styles into the main.css', () => {
return gulp.src([paths.tmp.styles["public"] + '*.css', paths.tmp.styles + '*.css'])
.pipe($.concat('main.css'))
.pipe(gulp.dest(paths.tmp.styles["public"]));
});
gulp.task('styles-private:concat', 'Concat all styles into the main.css', () => {
return gulp.src([paths.tmp.styles["private"] + '*.css', paths.tmp.styles + '*.css'])
.pipe($.concat('main.css'))
.pipe(gulp.dest(paths.tmp.styles["private"]));
});
/**
* The 'images' task copies images to `build / dist` directory.
*/
gulp.task('images:select2', 'Copies select2.png to `build/dist/public/styles` directory', () => {
return gulp.src('app/css/*.png')
.pipe(gulp.dest(paths.build.dist["public"].styles));
});
gulp.task('images:public', 'Copies images to `build/dist/public` directory', ['images:select2'], () => {
return gulp.src(paths.app.images)
.pipe(gulp.dest(paths.build.dist["public"].images))
.on('error', notifyOnError())
.pipe($.size({
title: 'images'
}));
});
gulp.task('images:private', 'Copies images to `build/dist/private` directory', () => {
return gulp.src(paths.app.images)
.pipe(gulp.dest(paths.build.dist["private"].images))
.on('error', notifyOnError())
.pipe($.size({
title: 'images'
}));
});
gulp.task('images:jquery', 'Copies jquery images to `build/dist/styles/images` directory', () => {
return gulp.src('jspm_packages/github/components/jqueryui@1.11.4/themes/base/images/**', {
base: 'jspm_packages/github/components/jqueryui@1.11.4/themes/base/'
})
.pipe(gulp.dest(argv.env === 'development' ? paths.tmp.styles.vendor : paths.build.dist["private"].styles))
.on('error', notifyOnError())
.pipe($.size({
title: 'images:jquery'
}));
});
/**
* The 'fonts' task copies fonts to `build / dist` directory.
*/
gulp.task('fonts:public', 'Copy fonts to `build/dist/public` directory', () => {
return gulp.src(paths.app.fonts)
.pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
.pipe($.flatten()).on('error', notifyOnError())
.pipe(gulp.dest(paths.build.dist["public"].fonts))
.pipe($.size({
title: 'fonts'
}));
});
gulp.task('fonts:private', 'Copy fonts to `build/dist/private` directory', () => {
return gulp.src(paths.app.fonts).pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
.pipe($.flatten())
.on('error', notifyOnError())
.pipe(gulp.dest(paths.build.dist["private"].fonts))
.pipe($.size({
title: 'fonts'
}));
});
/**
* Create JS production bundle.
*/
gulp.task('bundle-public', 'Create JS production bundle', ['jshint'], () => {
return gulp.src('')
.pipe($.shell(["jspm bundle-sfx app/scripts/app-public.js " + paths.tmp.scripts["public"] + "build.js"]))
.on('error', notifyOnError());
});
gulp.task('bundle-private', 'Create JS production bundle', ['jshint'], () => {
return gulp.src('')
.pipe($.shell(["jspm bundle-sfx app/scripts/app-private.js " + paths.tmp.scripts["private"] + "build.js"]))
.on('error', notifyOnError());
});
/**
* Compile production index.html for public app
*/
gulp.task('compile-public', 'Compile all JS, CSS and HTML files', ['bundle-public'], () => {
return gulp.src(paths.app.publicHtml)
.pipe($.inject(gulp.src(''), {
starttag: '<!-- inject:body-ng-app -->',
transform: () => {
return "<body ng-app='app' > ";
}
}))
.pipe($.inject(gulp.src(paths.tmp.scripts["public"] + 'build.js', {
read: false
})))
.on('error', notifyOnError()).pipe($.usemin({
css: [
$.bytediff.start(),
$.minifyCss({
keepSpecialComments: 0
}),
$.bytediff.stop(bytediffFormatter),
$.rev()
],
js: [
$.bytediff.start(),
$.ngAnnotate(),
$.uglify(),
$.bytediff.stop(bytediffFormatter),
$.rev()
],
html: [
$.bytediff.start(),
$.minifyHtml({
empty: true
}),
$.bytediff.stop(bytediffFormatter)
]
})).on('error', notifyOnError())
.pipe(gulp.dest(paths.build.dist["public"].basePath))
.pipe($.size({
title: 'compile-public',
showFiles: true
}));
});
/**
* Compile production index.html for public app
*/
gulp.task('compile-private', 'Compile all JS, CSS and HTML files', ['bundle-private'], () => {
return gulp.src(paths.app.privateHtml)
.pipe($.inject(gulp.src(''), {
starttag: '<!-- inject:body-ng-app -->',
transform: () => {
return "<body ng-app='app' > ";
}
}))
.pipe($.inject(gulp.src(paths.tmp.scripts["private"] + 'build.js', {
read: false
})))
.on('error', notifyOnError())
.pipe($.usemin({
css: [
$.bytediff.start(),
$.minifyCss({
keepSpecialComments: 0
}),
$.bytediff.stop(bytediffFormatter),
$.rev()
],
js: [
$.bytediff.start(),
$.ngAnnotate(),
$.uglify(),
$.bytediff.stop(bytediffFormatter),
$.rev()
],
html: [
$.bytediff.start(),
$.minifyHtml({
empty: true
}),
$.bytediff.stop(bytediffFormatter)
]
}))
.on('error', notifyOnError())
.pipe(gulp.dest(paths.build.dist["private"].basePath))
.pipe($.size({
title: 'compile-private',
showFiles: true
}));
});
//=============================================
// MAIN TASKS
//=============================================
//---------------------------------------------
// DEVELOPMENT TASKS
//---------------------------------------------
/**
* The 'serve' task serve the dev environment.
*/
gulp.task('serve', 'Serve for the dev environment', [
'styles-public:custom',
'styles-private:custom',
'images:jquery',
'styles:vendor',
'config'
], () => {
log(COLORS.blue('********** RUNNING SERVER **********'));
startBrowserSync([paths.tmp.basePath, 'app', 'build', 'jspm_packages', './']);
gulp.watch([paths.app.images], [browserSync.reload]).on('change', browserSync.reload);
gulp.watch(paths.app.styles["public"], ['styles-public:custom', browserSync.reload]);
gulp.watch(paths.app.styles["private"], ['styles-private:custom', browserSync.reload]);
gulp.watch([paths.app.scripts], ['jshint', browserSync.reload]);
return gulp.watch(paths.app.html, browserSync.reload);
});
gulp.task('serve:prod', 'Serve for the prod environment', () => {
return startBrowserSync([paths.build.dist["public"].basePath, paths.build.dist["private"].basePath]);
});
//---------------------------------------------
// BUILD TASKS
//---------------------------------------------
/**
* The 'build' task gets app ready for deployment by processing files
* and put them into directory ready for production.
*/
gulp.task('build', 'build application for production', function (cb) {
log(COLORS.blue('********** RUNNING BUILD **********'));
return runSequence(
['clean'],
['styles-public:custom', 'styles-private:custom', 'styles:vendor'],
['styles-public:concat', 'styles-private:concat', 'config'],
['compile-public', 'compile-private', 'images:private', 'images:jquery', 'images:public', 'fonts:private', 'fonts:public'], cb);
});
gulp.task('build:public', 'build application for production', function (cb) {
log(COLORS.blue('********** RUNNING BUILD of PUBLIC APP**********'));
return runSequence(
['clean'],
['styles-public:custom', 'styles:vendor'],
['styles-public:concat', 'config'],
['compile-public', 'images:public', 'fonts:public'], cb);
});
gulp.task('build:private', 'build application for production', function (cb) {
log(COLORS.blue('********** RUNNING BUILD of PRIVATE APP**********'));
return runSequence(
['clean'],
['styles-private:custom', 'styles:vendor'],
['styles-private:concat', 'config'],
['compile-private', 'images:private', 'images:jquery', 'fonts:private'], cb);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment