// gulpfile.js // Copyright (C) 2021 Digital Telepresence, LLC // License: Apache-2.0 'use strict'; const path = require('path'); const gulp = require('gulp'); const nodemon = require('gulp-nodemon'); const plumber = require('gulp-plumber'); const less = require('gulp-less'); const jshint = require('gulp-jshint'); const webpack = require('webpack-stream'); const { GenerateSW } = require('workbox-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const browserSync = require('browser-sync').create(); function util_start_browsersync ( ) { return new Promise((resolve, reject) => { browserSync.init({ proxy: { target: 'http://dev.base.digitaltelepresence.com:3010', ws: true, reqHeaders: { 'X-Forwarded-For': '127.0.0.1', 'X-Forwarded-Proto': 'https', }, cookies: { stripDomain: false }, }, host: 'dev.base.digitaltelepresence.com', open: 'external', https: { key: path.join(__dirname, 'ssl', 'dtp-base.key'), cert: path.join(__dirname, 'ssl', 'dtp-base.crt'), }, port: 3310, cors: true, ui: { port: 3610, }, notify: false, ghostMode: { clicks: false, forms: false, scroll: true, }, logLevel: 'info', callbacks: { ready: function (err, bs) { if (err) { console.log('BrowserSync start error', err); return reject(err); } console.log('BrowserSync ready'); return resolve(bs); }, }, }); }); } async function dtp_less_dark ( ) { return gulp .src('./client/less/dtp-dark.less') .pipe(plumber()) .pipe(less({ paths: [ __dirname ], math: 'always' })) .pipe(gulp.dest('./dist/css')) .pipe(browserSync.stream()); } async function dtp_less_light ( ) { return gulp .src('./client/less/dtp-light.less') .pipe(plumber()) .pipe(less({ paths: [ __dirname ], math: 'always' })) .pipe(gulp.dest('./dist/css')) .pipe(browserSync.stream()); } function dtp_jshint_client ( ) { var jsrc = 'client/js/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) .pipe(jshint.reporter('fail')) .pipe(browserSync.stream()) ; } function dtp_jshint_lib ( ) { var jsrc = 'lib/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) .pipe(jshint.reporter('fail')) .pipe(browserSync.stream()) ; } function dtp_jshint_workers ( ) { var jsrc = 'app/workers/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) ; } function dtp_jshint_services ( ) { var jsrc = 'app/services/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) ; } function dtp_jshint_models ( ) { var jsrc = 'app/models/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) .pipe(jshint.reporter('fail')) .pipe(browserSync.stream()) ; } function dtp_jshint_controllers ( ) { var jsrc = 'app/controllers/**/*.js'; return gulp .src(jsrc) .pipe(jshint()) .pipe(jshint.reporter('dtp-jshint-reporter')) .pipe(jshint.reporter('fail')) .pipe(browserSync.stream()) ; } /* * Shared Webpack settings detween dev & prod */ const webpackDevtool = 'source-map'; const webpackResolve = { alias: { dtp: path.resolve(__dirname, 'lib', 'client', 'js'), }, extensions: ['.js'], }; const webpackOutput = { filename: 'dtpweb-[name].js', path: path.resolve(__dirname, 'dist', 'js') }; /* * Webpack dev build */ function dtp_jsbuild_dev ( ) { var jsrc = 'client/js/index.js'; var jdst = 'dist/js'; return gulp .src(jsrc) .pipe(webpack({ mode: 'development', devtool: webpackDevtool, resolve: webpackResolve, entry: { "app": './client/js/index.js', "admin": './client/js/index-admin.js', }, output: webpackOutput, plugins: [ new GenerateSW({ swDest: 'service_worker.js', }), ], performance: { hints: false, maxEntrypointSize: 512 * 1024, maxAssetSize: 512 * 1024, }, })) .on('error', function (err) { console.log(err.toString()); }) .pipe(gulp.dest(jdst)) ; } /* * Webpack prod build */ function dtp_jsbuild_prod ( ) { var jsrc = 'client/js/index.js'; var jdst = 'dist/js'; return gulp .src(jsrc) .pipe(webpack({ mode: 'production', devtool: webpackDevtool, resolve: webpackResolve, entry: { "app.min": './client/js/index.js', "admin.min": './client/js/index-admin.js', }, optimization: { minimize: true, minimizer: [new TerserPlugin({ extractComments: true, })], }, output: webpackOutput, plugins: [ new GenerateSW({ swDest: 'service_worker.min.js', }), ], performance: { hints: false, maxEntrypointSize: 512 * 1024, maxAssetSize: 512 * 1024, }, })) .on('error', function (err) { console.log(err.toString()); }) .pipe(gulp.dest(jdst)) ; } function dtp_watch_client (done) { var files = [ './client/less/**/*.less', ]; gulp.watch(files, exports.less); var jsfiles = [ path.join(__dirname, '..', 'dtp', 'dtp-lib', 'client', '**', '*.js'), path.join(__dirname, 'client', 'js', '**', '*.js'), ]; gulp.watch(jsfiles, gulp.series( dtp_jshint_client, // check syntax, etc. gulp.parallel( dtp_jsbuild_dev, // build dev webpack dtp_jsbuild_prod, // build prod webpack ), function reload (done) { browserSync.reload(); return done(); }, )); var workerFiles = ['app/workers/*.js']; gulp.watch(workerFiles, dtp_jshint_workers); var serviceFiles = ['app/services/**/*.js']; gulp.watch(serviceFiles, dtp_jshint_services); done(); } function dtp_develop (done) { var isFirst = true; nodemon({ script: 'dtp-webapp.js', verbose: false, watch: [ './*.js', './config/**/*.js', 'lib/**/*.js', 'app/**/*.js', 'app/views/**/*.pug', 'app/templates/**/*.pug', 'app/services/**/*.js', 'app/workers/**/*.js', ], ext: 'js pug', stdout: false, done: done }) .on('readable', function ( ) { this.stdout.on('data', (chunk) => { if (/platform online/.test(chunk)) { if (isFirst) { util_start_browsersync(); isFirst = false; } else { browserSync.reload(); } } }); this.stdout.pipe(process.stdout); this.stderr.pipe(process.stderr); }); } exports.less = gulp.series( dtp_less_light, dtp_less_dark, ); exports.jshint = gulp.parallel( dtp_jshint_models, dtp_jshint_lib, dtp_jshint_controllers, dtp_jshint_client, dtp_jshint_workers, dtp_jshint_services, ); exports.build = gulp.parallel( exports.less, exports.jshint, dtp_jsbuild_dev, dtp_jsbuild_prod, ); exports.default = gulp.series( exports.build, gulp.parallel(dtp_watch_client, dtp_develop) );