var gulp = require('gulp'), del = require('del'), _ = require('lodash'), fs = require('fs'), path = require('path'), concat = require('gulp-concat'), sass = require('gulp-sass'), postcss = require('gulp-postcss'), cleanCSS = require('gulp-clean-css'), sourcemaps = require('gulp-sourcemaps'), autoprefixer = require('autoprefixer'), merge = require('merge-stream'), rename = require('gulp-rename'), inject = require('gulp-inject'), uglify = require('gulp-uglify'), eslint = require('gulp-eslint'), cachebust = require('gulp-cache-bust'), connectModRewrite = require('connect-modrewrite'), connect = require('gulp-connect'), through = require('through2'), gulp_if = require('gulp-if'), replace = require('gulp-replace'); // development task var production = false; let timestamp; var scripts = JSON.parse(fs.readFileSync('frontend/app.scripts.json')); var styles = JSON.parse(fs.readFileSync('frontend/app.styles.json')); var configJson = JSON.parse(fs.readFileSync('frontend/src/js/config.json')); function clean() { return del(['frontend/dist/*']); }; /* Concat all js libs */ function vendorjs() { var paths = []; _.forIn(scripts.chunks, function(chunkScripts, chunkName) { chunkScripts.forEach(function(script) { var scriptFileName = scripts.paths[script]; if (!fs.existsSync(__dirname + '/' + scriptFileName)) { throw console.error('Required path doesn\'t exist: ' + __dirname + '/' + scriptFileName, script) } paths.push(scriptFileName); }); }); return gulp.src(paths) .pipe(concat('vendor.js')) .pipe(gulp.dest("frontend/dist/vendors")) } /* Concat all css libs */ function vendorcss() { var paths = []; _.forIn(styles.chunks, function(chunkStyles, chunkName) { chunkStyles.forEach(function(style) { var styleFileName = styles.paths[style]; if (!fs.existsSync(__dirname + '/' + styleFileName)) { throw console.error('Required path doesn\'t exist: ' + __dirname + '/' + styleFileName, style) } paths.push(styleFileName); }); }); return gulp.src(paths) .pipe(concat('vendor.css')) .pipe(gulp.dest("frontend/dist/vendors")) } /* minify and compress custom css files */ function css() { return gulp.src('frontend/src/css/main.scss') .pipe(sass().on('error', sass.logError)) .pipe(sourcemaps.init()) .pipe(postcss([autoprefixer()])) .pipe(gulp_if(production, cleanCSS())) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(sourcemaps.write()) .pipe(gulp.dest('frontend/dist/css')) pipe(connect.reload()); } /* minify angular scripts */ function js() { var app = gulp.src('frontend/src/js/app.js') .pipe(concat('app.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')); var configs = gulp.src('frontend/src/js/route-config/*.js') .pipe(concat('route-config.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')); var controllers = gulp.src('frontend/src/js/controllers/*.js') .pipe(concat('controllers.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')); var directives = gulp.src('frontend/src/js/directives/*.js') .pipe(concat('directives.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')) var filters = gulp.src('frontend/src/js/filters/*.js') .pipe(concat('filters.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')); var services = gulp.src('frontend/src/js/services/*.js') .pipe(concat('services.js')) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp_if(production, uglify({ mangle: false }))) .pipe(gulp.dest('frontend/dist/js')) return merge(app, configs, controllers, directives, filters, services). pipe(connect.reload()); } /* minify and compress html files */ function html() { return gulp.src('frontend/src/views/web/**/*.html') // .pipe(gulp_if(production, htmlmin({ collapseWhitespace: true }))) .pipe(gulp.dest('frontend/dist/views/web/')) .pipe(connect.reload()); } /* for image compression */ function images() { return gulp.src('frontend/src/images/**/*') // .pipe(gulp_if(production, imagemin())) .pipe(gulp.dest('frontend/dist/images')); } /* Fonts */ function fonts() { var font = gulp.src([ 'bower_components/font-awesome/fonts/fontawesome-webfont.*', 'bower_components/materialize/fonts/**/*', 'frontend/src/fonts/*' ]) .pipe(gulp.dest('frontend/dist/fonts/')); var fontCss = gulp.src([ 'bower_components/font-awesome/css/font-awesome.css' ]) .pipe(gulp_if(production, cleanCSS())) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(sourcemaps.write()) .pipe(gulp.dest('frontend/dist/css/')); return merge(font, fontCss); } /* config for prod server */ function configProd() { return gulp.src('frontend/src/js/config.sample.js') .pipe(replace('moduleName', 'evalai-config')) .pipe(replace('constantName', Object.keys(configJson.production))) .pipe(replace('configKey', Object.keys(configJson.production.EnvironmentConfig))) .pipe(replace('configValue', configJson.production.EnvironmentConfig.API)) .pipe(rename({ basename: 'config' })) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp.dest('frontend/dist/js')) } /* config for staging server */ function configStaging() { return gulp.src('frontend/src/js/config.sample.js') .pipe(replace('moduleName', 'evalai-config')) .pipe(replace('constantName', Object.keys(configJson.staging))) .pipe(replace('configKey', Object.keys(configJson.staging.EnvironmentConfig))) .pipe(replace('configValue', configJson.staging.EnvironmentConfig.API)) .pipe(rename({ basename: 'config' })) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp.dest('frontend/dist/js/')) } /* config for dev server */ function configDev() { return gulp.src('frontend/src/js/config.sample.js') .pipe(replace('moduleName', 'evalai-config')) .pipe(replace('constantName', Object.keys(configJson.local))) .pipe(replace('configKey', Object.keys(configJson.local.EnvironmentConfig))) .pipe(replace('configValue', configJson.local.EnvironmentConfig.API)) .pipe(rename({ basename: 'config' })) .pipe(gulp_if(production, rename({ suffix: '.min' }))) .pipe(gulp.dest('frontend/dist/js/')) } /* Inject path of css and js files in index.html */ function injectpaths() { var target = gulp.src('frontend/base.html'); var sources = gulp.src([ 'frontend/dist/vendors/*.js', 'frontend/dist/js/*.js', 'frontend/dist/vendors/*.css', 'frontend/dist/css/*.css', ], { read: false }); return target .pipe(inject(sources, { ignorePath: 'frontend', addRootSlash: true })) .pipe(gulp_if('*.js', production ? uglify() : through.obj())) .pipe(gulp_if('*.css', production ? cleanCSS() : through.obj())) .pipe(production ? cachebust({ type: 'timestamp' }) : through.obj()) .pipe(through.obj((file, enc, cb) => { // Extract the timestamp value from the file contents const fileContents = file.contents.toString(); const regex = /\?t=(\d+)/; const matches = fileContents.match(regex); if (matches && matches[1]) { timestamp = matches[1]; } cb(null, file); })) .pipe(rename({ basename: "index" })) .pipe(gulp.dest('frontend/')); } function replacetimestamp() { return gulp.src('frontend/dist/**/*.*') .pipe(replace('___REPLACE_IN_GULP___', timestamp)) .pipe(gulp.dest('frontend/dist')); } /* js linting */ var lint_path = { js: ['frontend/src/js/**/*.js', ] } function lint() { return gulp.src(lint_path.js) .pipe(eslint({})) .pipe(eslint.format()) .pipe(eslint.results(function(results) { // Get the count of lint errors var countError = results.errorCount; //Get the count of lint warnings var countWarning = results.warningCount; if (countError === 0) { if (countWarning > 0) { console.warn("Please remove lint warnings in production env."); } } else { connect.serverClose(); console.error("Please remove lint errors to connect the server"); } })) .pipe(eslint.failAfterError()) } /* Start a server for serving frontend */ function startServer() { // initially close the existance server if exists connect.serverClose(); connect.server({ root: 'frontend/', port: 8888, host: '0.0.0.0', livereload: true, middleware: function(connect) { return [ connectModRewrite([ '!\\.html|\\.js|\\.css|\\.ico|\\.png|\\.gif|\\.jpg|\\.woff|.\\.ttf|.\\otf|\\.jpeg|\\.swf.*$ /index.html [NC,L]' ]) ]; } }); } function watch() { gulp.watch('frontend/src/js/**/*.js', js); gulp.watch('frontend/src/css/**/*.scss', css); gulp.watch('frontend/src/views/web/**/*.html', html); gulp.watch('frontend/src/images/**/*', images); gulp.watch('bower_components/materialize/fonts/**/*', fonts); gulp.watch('bower_components/materialize/fonts/**/*', fonts); } var parallelTasks = gulp.parallel(vendorcss, vendorjs, css, js, html, images, fonts); gulp.task('production', gulp.series(clean, function(done) { production = true; done(); }, parallelTasks, configProd, injectpaths, replacetimestamp, lint)); gulp.task('staging', gulp.series(clean, function(done) { production = true; done(); }, parallelTasks, configStaging, injectpaths, replacetimestamp, lint)); gulp.task('dev', gulp.series(clean, function(done) { production = false; done(); }, parallelTasks, configDev, injectpaths, lint)); gulp.task('dev:runserver', gulp.series(clean ,function(done) { production = false; done(); }, parallelTasks, configDev, injectpaths, lint, gulp.parallel(watch, startServer))); gulp.task('runserver', gulp.series(function(done) { production = false; done(); }, gulp.parallel(watch, startServer)));