I migrated gulp from 3.9.1 to Gulp 4.0.2. Converted all the task as per Gulp 4 guidelines, however when I run 'gulp' from command line, all the tasks until 'nodemon
'
starts and finishes, but when it is about to start 'nodemon
',
it tries to start and then again continue loading the processing again and again. Might have missed some config, due to which it is causing issue.
Sharing new (v4.0.2) Gulpfile for reference along with GulpVariables, along with start console log.
New File
var gulp = require('gulp'); // Include gulp
var runsequence = require('run-sequence'); // used to run the different gulp task in a sequence
var deleteFiles = require('del'); // used to delete the files in dist folder for every build
var inject = require('gulp-inject'); // used to inject js and css files to index.html
var nodemon = require('gulp-nodemon'); // used to start the node server and watch for changes
var sourcemaps = require('gulp-sourcemaps'); // used to hold information about original files after minify
var concat = require('gulp-concat'); // used to append a file
var uglify = require('gulp-uglify'); // used to minify the js file
var cleancss = require('gulp-clean-css'); // used to clean up the css file
var obfuscate = require('gulp-js-obfuscator'); // used to obfuscate js file
//var git = require('gulp-git'); // used to work with git repo from gulp
var replacePaths = require('gulp-replace-path'); // used to change the src path for cloned repo
var jshint = require('gulp-jshint'); // used to check js files for errors and warnings
var jshintReporter = require('gulp-jshint-html-reporter'); // reporter to view the errors and warnings
var babel = require('gulp-babel'); // used to convert ES6 to ES5 because ES6 is not supported by uglify
var minifyImages = require('gulp-imagemin'); // used to minify images
var minifyejs = require('gulp-minify-ejs'); // used to minify mail templates which is in .ejs format
var liveReload = require('gulp-livereload'); // used to auromatically reload the browser when we change code
var gulpIf = require('gulp-if'); // execute a function based on a condition
var cache = require('gulp-cached'); // used to perform task only on changed files while watching
var chug = require('gulp-chug'); // used to run external gulpfile in case of remote build
var merge = require('merge-stream'); // used to have multiple source in single task
var rename = require('gulp-rename'); // used to have multiple source in single task
var gulpVariables = require('./gulpVariables.json'); // external file that contains directory path and other variables for the build
// removes the old files from the directory so that we get a clean build each time
function clean() {
return deleteFiles([gulpVariables.dist, gulpVariables.clone, gulpVariables.codeReviewReportName]); // delete the directory
};
//task to clone from remote repo
function cloneRepo() {
return git.clone(gulpVariables.remoteRepoUrl,{args: './'+gulpVariables.clone}, function (err) {
if (err) throw err;
process.chdir(gulpVariables.clone);
});
};
//task to checkout branch in local repo cloned from remote
function checkoutRepo() {
return git.checkout(gulpVariables.repoBranchName, function (err) {
if (err) throw err;
process.chdir('..');
});
};
function runGulpfileInsideClone() {
return gulp.src(gulpVariables.clone+'/gulpfile.js',{read:false})
.pipe(chug());
};
//review all js files for error
function staticCodeReview() {
return gulp.src([
gulpVariables.src + '/*.js',
gulpVariables.apiSrc + '/*.js',
gulpVariables.jsSrc + '/*.js',
gulpVariables.jsSrc + '/**/*.js',
gulpVariables.schedulerSrc + '/*.js'
])
.pipe(jshint())
.pipe(jshint.reporter(jshintReporter, {
filename: gulpVariables.codeReviewReportName
})
);
};
//copy src files without the nodeserver.js and folders to dist
function copySourceFoldersWithoutJSFiles() {
//Pass in all files in the root w/ no subdirectories to dist
//dot:true to make sure to copy .cfignore file
//.cfignore contains files to ignore to deploy in bluemix
var src = gulp.src([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], {dot: true});
var dest = gulp.dest(gulpVariables.dist);
return src.pipe(dest);
};
// copy vendor css files to dist
function copyVendorCSSFiles() {
return gulp.src(gulpVariables.vendorCSSSrc + '/**/*.css')
.pipe(concat(gulpVariables.combinedVendorCSSFileName))
.pipe(gulp.dest(gulpVariables.cssDest));
};
copyVendorCSSFiles.description = 'copy vendor css files to dist';
// optimise vendor css files in dist
async function optimiseVendorCSSFiles() {
if(gulpVariables.isOptimiseCSS) {
return gulp.src(gulpVariables.cssDest + '/' + gulpVariables.combinedVendorCSSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(cleancss())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(gulp.dest(gulpVariables.cssDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
};
optimiseVendorCSSFiles.description = 'optimise vendor css files in dist';
// copy vendor images to dist
function copyVendorImages() {
return gulp.src(gulpVariables.vendorImgSrc + '/**/*')
.pipe(gulp.dest(gulpVariables.imgDest));
};
// optimise vendor images in dist
async function optimiseVendorImages() {
if(gulpVariables.isOptimiseImages) {
return gulp.src(gulpVariables.vendorImgDest)
.pipe(minifyImages())
.pipe(gulp.dest(gulpVariables.vendorImgDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
};
// copy vendor js files to dist
function copyVendorJSFiles() {
var vendorJSWithoutPDFWorker = gulp.src([
gulpVariables.vendorJSSrc + '/**/angular.js', // this must be first
gulpVariables.vendorJSSrc + '/**/*.js', // all other files
'!' + gulpVariables.vendorJSSrc + '/**/pdf.worker.js'
])
.pipe(concat(gulpVariables.combinedVendorJSFileName))
.pipe(gulp.dest(gulpVariables.jsDest));
// ignoring the pdf.worker.js in the concatenated vendor file because for the PDF view it searches file with name pdf.worker.js
var PDFWorkerJS =gulp.src(gulpVariables.vendorJSSrc + '/vendor/pdf.worker.js')
.pipe(rename('vendor.min.worker.js'))
.pipe(gulp.dest(gulpVariables.jsDest));
return merge(vendorJSWithoutPDFWorker, PDFWorkerJS);
};
// optimise vendor js files in dist
async function optimiseVendorJSFiles() {
if(gulpVariables.isOptimiseJS) {
return gulp.src(gulpVariables.jsDest + '/' + gulpVariables.combinedVendorJSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(uglify())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(gulp.dest(gulpVariables.jsDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
};
// copy external css to dist
function copyCSSFiles() {
return gulp.src(gulpVariables.cssSrc + '/*.css')
.pipe(concat(gulpVariables.combinedAppCSSFileName))
.pipe(gulp.dest(gulpVariables.cssDest));
};
// optimise external css in dist
async function optimiseCSSFiles() {
if(gulpVariables.isOptimiseCSS){
return gulp.src(gulpVariables.cssDest + '/' + gulpVariables.combinedAppCSSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(cleancss())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(gulp.dest(gulpVariables.cssDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
};
// copy images to dist
function copyImages() {
return gulp.src(gulpVariables.imgSrc + '/*')
.pipe(gulp.dest(gulpVariables.imgDest));
};
// optimise images in dist
async function optimiseImages() {
if(gulpVariables.isOptimiseImages){
return gulp.src(gulpVariables.imgDest + '/*')
.pipe(minifyImages())
.pipe(gulp.dest(gulpVariables.imgDest))
.pipe(gulpIf(gulpVariables.env == 'dev', liveReload()));
}
};
// copy js files to dist
function copyJSFiles() {
return gulp.src([
gulpVariables.jsSrc + '/app.js', // this must be first
gulpVariables.jsSrc + '/**/*.js' // all other files
])
.pipe(concat(gulpVariables.combinedAppJSFileName))
.pipe(gulp.dest(gulpVariables.jsDest));
};
// optimise js files in dist
async function optimiseJSFiles() {
if(gulpVariables.isOptimiseJS) {
return gulp.src(gulpVariables.jsDest + '/' + gulpVariables.combinedAppJSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(babel({
presets: ['es2015']
}))
.pipe(uglify())
.pipe(obfuscate())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(gulp.dest(gulpVariables.jsDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
};
// copy nodeserver.js to dist
function copyNodeServerFile() {
return gulp.src(gulpVariables.src + '*.js')
.pipe(gulp.dest(gulpVariables.dist));
};
// optimise nodeserver.js in dist
async function optimiseNodeServerFile() {
if(gulpVariables.isOptimiseJS) {
return gulp.src(gulpVariables.dist + '/*.js')
.pipe(gulpIf(gulpVariables.env == 'prod',babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod',uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod',obfuscate()))
.pipe(gulp.dest(gulpVariables.dist));
}
};
// copy api files to dist
function copyApiFiles() {
return gulp.src(gulpVariables.apiSrc + '/**/*.js')
.pipe(gulp.dest(gulpVariables.apiDest));
};
// optimise api files in dist
async function optimiseApiFiles() {
if(gulpVariables.isOptimiseJS) {
return gulp.src(gulpVariables.apiDest + '/**/*.js')
.pipe(cache())
.pipe(gulpIf(gulpVariables.env == 'prod',babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod', uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod', obfuscate()))
.pipe(gulp.dest(gulpVariables.apiDest));
}
};
// copy mail templates to dist
function copyMailTemplates() {
return gulp.src(gulpVariables.mailTemplateSrc + '/**')
.pipe(gulp.dest(gulpVariables.mailTemplateDest));
};
// optimise mail templates in dist
async function optimiseMailTemplates() {
if(gulpVariables.isOptimiseJS) {
gulp.src(gulpVariables.mailTemplateDest + '/**')
.pipe(minifyejs())
.pipe(gulp.dest(gulpVariables.mailTemplateDest));
}
};
// copy scheduler to dist
function copySchedulerFiles() {
return gulp.src(gulpVariables.schedulerSrc + '/*.js')
.pipe(gulp.dest(gulpVariables.schedulerDest));
};
// optimise scheduler in dist
async function optimiseSchedulerFiles() {
if(gulpVariables.isOptimiseJS) {
return gulp.src(gulpVariables.schedulerDest + '/*.js')
.pipe(gulpIf(gulpVariables.env == 'prod', babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod', uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod', obfuscate()))
.pipe(gulp.dest(gulpVariables.schedulerDest));
}
};
// group all vendor copy tasks
const copyAndOptimiseVendorCSSFiles = gulp.series(copyVendorCSSFiles, optimiseVendorCSSFiles);
const copyAndOptimiseVendorImages = gulp.series(copyVendorImages, optimiseVendorImages);
const copyAndOptimiseVendorJSFiles = gulp.series(copyVendorJSFiles, optimiseVendorJSFiles);
const copyAndOptimiseVendorFiles = gulp.series(gulp.parallel(copyAndOptimiseVendorCSSFiles, copyAndOptimiseVendorImages, copyAndOptimiseVendorJSFiles));
const copyAndOptimiseCSSFiles = gulp.series(copyCSSFiles, optimiseCSSFiles);
const copyAndOptimiseImages = gulp.series(copyImages, optimiseImages);
// copy html files to dist
function copyHtmlFiles() {
return gulp.src(gulpVariables.htmlSrc + '/**')
.pipe(cache())
.pipe(gulp.dest(gulpVariables.htmlDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
const copyAndOptimiseJSFiles = gulp.series(copyJSFiles, optimiseJSFiles);
// group all client side app files copy tasks
const copyAndOptimiseClientSideAppFiles = gulp.series(gulp.parallel(copyAndOptimiseCSSFiles, copyAndOptimiseImages, copyHtmlFiles, copyAndOptimiseJSFiles));
const copyAndOptimiseNodeServerFile = gulp.series(copyNodeServerFile, optimiseNodeServerFile);
const copyAndOptimiseApiFiles = gulp.series(copyApiFiles, optimiseApiFiles);
const copyAndOptimiseMailTemplates = gulp.series(copyMailTemplates, optimiseMailTemplates);
const copyAndOptimiseSchedulerFiles = gulp.series(copySchedulerFiles, optimiseSchedulerFiles);
// group all server side app files copy tasks
const copyAndOptimiseServerSideAppFiles = gulp.series(gulp.parallel(copyAndOptimiseNodeServerFile, copyAndOptimiseApiFiles, copyAndOptimiseMailTemplates, copyAndOptimiseSchedulerFiles));
function copyCertificates(){
return gulp.src(gulpVariables.certSrc + '/*.*')
.pipe(gulp.dest(gulpVariables.certDest));
};
// copy index html file to dist
function injectIndexFile() {
var jsSrc,cssSrc,injectSrc;
jsSrc = [
gulpVariables.jsDest + '/vendor.min.js',
gulpVariables.jsDest + '/vendor.min.worker.js',
gulpVariables.jsDest + '/' + gulpVariables.combinedAppJSFileName
];
cssSrc = [
gulpVariables.cssDest + '/' + gulpVariables.combinedVendorCSSFileName,
gulpVariables.cssDest + '/' + gulpVariables.combinedAppCSSFileName
];
injectSrc = jsSrc.concat(cssSrc);
gulp.src(gulpVariables.indexSrc + '/index.html')
.pipe(inject(gulp.src(injectSrc),
{ignorePath: 'dist/public', addRootSlash: false}
))
.pipe(gulp.dest(gulpVariables.indexDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
function injectIndexFileVanillaCopy() {
return gulp.src(gulpVariables.indexSrc + '/index.html')
.pipe(gulp.dest(gulpVariables.indexDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
// nodemon to start the server
function nodemon() {
if(gulpVariables.env == 'dev') {
nodemon({
script: gulpVariables.dist + '/' + gulpVariables.nodeServerFileName,
ext: 'js',
delay: "10000",
watch:[gulpVariables.apiDest, gulpVariables.dist + gulpVariables.nodeServerFileName, gulpVariables.schedulerDest]
});
}
};
// Watch Files For Changes and calls the gulp task if any change happens
function watch() {
if(gulpVariables.env == 'dev') {
liveReload.listen();
watch([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], copySourceFoldersWithoutJSFiles);
watch(gulpVariables.src + '*.js', copyAndOptimiseNodeServerFile);
watch(gulpVariables.apiSrc + '/**/*.js', copyAndOptimiseApiFiles);
watch(gulpVariables.mailTemplateSrc + '/**', copyAndOptimiseMailTemplates);
watch(gulpVariables.schedulerSrc + '/*.js', copyAndOptimiseSchedulerFiles);
watch(gulpVariables.cssSrc + '/*.css', copyAndOptimiseCSSFiles);
watch(gulpVariables.imgSrc + '/*', copyAndOptimiseImages);
watch(gulpVariables.htmlSrc + '/**', copyHtmlFiles);
watch(gulpVariables.jsSrc + '/**', copyAndOptimiseJSFiles);
watch(gulpVariables.indexSrc + '/index.html', injectIndexFileVanillaCopy);
watch(gulpVariables.vendorCSSSrc + '/**', copyAndOptimiseVendorCSSFiles);
watch(gulpVariables.vendorImgSrc + '/**', copyAndOptimiseVendorImages);
watch(gulpVariables.vendorJSSrc + '/**', copyAndOptimiseVendorJSFiles);
}
};
/*
* Specify if tasks run in series or parallel using `gulp.series` and `gulp.parallel`
*/
var build = gulp.series(clean, copySourceFoldersWithoutJSFiles, copyAndOptimiseVendorFiles, copyAndOptimiseClientSideAppFiles, copyAndOptimiseServerSideAppFiles, copyCertificates, injectIndexFileVanillaCopy, nodemon);
//var build = gulp.series(server, watch);
/*
* You can use CommonJS `exports` module notation to declare tasks
*/
/*exports.clean = clean;
exports.cloneRepo = cloneRepo;
exports.staticCodeReview = staticCodeReview;
exports.checkoutRepo = checkoutRepo;
exports.copySourceFoldersWithoutJSFiles = copySourceFoldersWithoutJSFiles;
exports.copyVendorCSSFiles = copyVendorCSSFiles;
exports.optimiseVendorCSSFiles = optimiseVendorCSSFiles;
exports.copyAndOptimiseVendorCSSFiles = copyAndOptimiseVendorCSSFiles;
exports.copyVendorImages = copyVendorImages
exports.optimiseVendorImages = optimiseVendorImages;
exports.copyAndOptimiseVendorImages = copyAndOptimiseVendorImages;
exports.copyVendorJSFiles = copyVendorJSFiles;
exports.optimiseVendorJSFiles = optimiseVendorJSFiles;
exports.copyAndOptimiseVendorJSFiles = copyAndOptimiseVendorJSFiles;
exports.copyAndOptimiseVendorFiles = copyAndOptimiseVendorFiles;
exports.copyCSSFiles = copyCSSFiles;
exports.optimiseCSSFiles = optimiseCSSFiles;
exports.copyAndOptimiseCSSFiles = copyAndOptimiseCSSFiles;
exports.copyImages = copyImages;
exports.optimiseImages = optimiseImages;
exports.copyAndOptimiseImages = copyAndOptimiseImages
exports.copyHtmlFiles = copyHtmlFiles;
exports.copyJSFiles = copyJSFiles;
exports.optimiseJSFiles = optimiseJSFiles;
exports.copyAndOptimiseJSFiles = copyAndOptimiseJSFiles;
exports.copyAndOptimiseClientSideAppFiles = copyAndOptimiseClientSideAppFiles;
exports.copyNodeServerFile = copyNodeServerFile;
exports.optimiseNodeServerFile = optimiseNodeServerFile;
exports.copyAndOptimiseNodeServerFile = copyAndOptimiseNodeServerFile;
exports.copyApiFiles = copyApiFiles;
exports.optimiseApiFiles = optimiseApiFiles;
exports.copyAndOptimiseApiFiles = copyAndOptimiseApiFiles;
exports.copyMailTemplates = copyMailTemplates;
exports.optimiseMailTemplates = optimiseMailTemplates;
exports.copyAndOptimiseMailTemplates = copyAndOptimiseMailTemplates;
exports.copySchedulerFiles = copySchedulerFiles;
exports.optimiseSchedulerFiles = optimiseSchedulerFiles;
exports.copyAndOptimiseSchedulerFiles = copyAndOptimiseSchedulerFiles;
exports.copyAndOptimiseServerSideAppFiles = copyAndOptimiseServerSideAppFiles;
exports.copyCertificates = copyCertificates;
exports.injectIndexFileVanillaCopy = injectIndexFileVanillaCopy;
exports.nodemon = nodemon;
exports.watch = watch;*/
/*
* Define default task that can be called by just running `gulp` from cli
*/
exports.default = build;
Gulp Variables File
{
"src": "src/",
"dist": "dist",
"apiSrc": "src/api",
"apiDest": "dist/api",
"certSrc": "src/certificate",
"certDest": "dist/certificate",
"mailTemplateSrc": "src/mailTemplates",
"mailTemplateDest": "dist/mailTemplates",
"schedulerSrc": "src/scheduler",
"schedulerDest": "dist/scheduler",
"cssSrc": "src/public/css",
"cssDest": "dist/public/css",
"imgSrc": "src/public/images",
"imgDest": "dist/public/images",
"vendorImgDest": "dist/public/images/vendor",
"htmlSrc": "src/public/html",
"htmlDest": "dist/public/html",
"jsSrc": "src/public/js",
"jsDest": "dist/public/js",
"vendorCSSSrc": "vendor/css",
"vendorImgSrc": "vendor/images",
"vendorJSSrc": "vendor/js",
"indexSrc": "src/public",
"indexDest": "dist/public",
"isRemoteBuild" : false,
"clone": "clone",
"remoteRepoUrl" : "",
"repoBranchName" : "dev",
"codeReviewReportName" : "codeReviewReport.html",
"env": "dev",
"combinedAppJSFileName":"app.min.js",
"combinedVendorJSFileName":"vendor.min.js",
"combinedAppCSSFileName":"app.min.css",
"combinedVendorCSSFileName":"vendor.min.css",
"combinedApiFileName":"api.min.js",
"nodeServerFileName":"nodeServer.js",
"isOptimiseCSS": false,
"isOptimiseJS":false,
"isOptimiseImages":false
}
When I run gulp
on command line, it all works fine (appears to be) till function/task - injectIndexFileVanillaCopy
. Moment I add nodemon
function/task, it tries to start the process and then again restarts it again and again as seen in below image/console output
Converted gulpfile from v 3.9.1 to v4.0.2, using series & parallel api with on change in execution order. Expecting to run/start the process cleanly, but server/node/process going in loop. Might be some config issue with watch
and nodemon
, unable to figure that out. Have gone thru multiple links, but not able to root cause
I have spent nearly 4-5 days screening through multiple topics, links for Gulp 3 --> Gulp 4 migration, but couldn't find any good/working solution that is fully utilizing Gulp 4 capabilities like, creating/exporting task
, creating/using functions
, using series/parallel
, watch
, run-sequence
and nodemon
features and lastly function callbacks
.
Eventually after multiple trial and error, I got the gulp 3.9.1 gulpfile
to gulp 4.0.2 version.
Sharing few things below from my learning, may be some of these are already in public domain.
Callback
- If function is return
ing, then no need to explicitly use done()
task
and hence need to be exported
(registered)run-sequence
npm
module, convert it to series
gulp
3.x task
created as below, possible suggestion is to convert it to parallel
OLD
gulp.task('copyAndOptimiseVendorFiles', ['copyAndOptimiseVendorCSSFiles','copyAndOptimiseVendorImages','copyAndOptimiseVendorJSFiles']);
NEW
const copyAndOptimiseVendorFiles = parallel(copyAndOptimiseVendorCSSFiles, copyAndOptimiseVendorImages, copyAndOptimiseVendorJSFiles);
watch
items define as below, then again a suggestion is to convert it like the one given as NEW approach.OLD
gulp.watch([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], ['copySourceFoldersWithoutJSFiles']);
NEW
watch([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], series(copySourceFoldersWithoutJSFiles));
While you upgrade gulp 3.x to 4.x, you might have few other node module, that are old, old as per current version of respective module. Please don't upgrade them to current version blindly. Run npm outdated
command to get the snapshot of what is outdated and needs to be updated.
Updated only those outdated npm
modules to 'Wanted' version instead of 'Latest' one.
Few keywords like watch
, nodemon
, are actually keywords and might create a problem in gulp 4.x. What I mean here is, you gulp 3.x will work with below function definition
gulp.task('nodemon', function() {....})
gulp.task('watch', function() {....})
but it might create problem in gulp 4.x. Please use different names for functions or task, as you would see in working version below.
I definitely found few URLs (stackoverflow
, youtube
) useful in order to build understanding about this migration and get it to work state. Can shore those if someone is really interested and curious.
Lastly sharing the working version, which I was hoping for when I posted this question.
Working gulpfile
//var gulp = require('gulp'); // Include gulp
var deleteFiles = require('del'); // used to delete the files in dist folder for every build
var inject = require('gulp-inject'); // used to inject js and css files to index.html
var nodemon = require('gulp-nodemon'); // used to start the node server and watch for changes
var sourcemaps = require('gulp-sourcemaps'); // used to hold information about original files after minify
var concat = require('gulp-concat'); // used to append a file
var uglify = require('gulp-uglify'); // used to minify the js file
var cleancss = require('gulp-clean-css'); // used to clean up the css file
var obfuscate = require('gulp-js-obfuscator'); // used to obfuscate js file
//var git = require('gulp-git'); // used to work with git repo from gulp
var replacePaths = require('gulp-replace-path'); // used to change the src path for cloned repo
var jshint = require('gulp-jshint'); // used to check js files for errors and warnings
var jshintReporter = require('gulp-jshint-html-reporter'); // reporter to view the errors and warnings
var babel = require('gulp-babel'); // used to convert ES6 to ES5 because ES6 is not supported by uglify
var minifyImages = require('gulp-imagemin'); // used to minify images
var minifyejs = require('gulp-minify-ejs'); // used to minify mail templates which is in .ejs format
var liveReload = require('gulp-livereload'); // used to auromatically reload the browser when we change code
var gulpIf = require('gulp-if'); // execute a function based on a condition
var cache = require('gulp-cached'); // used to perform task only on changed files while watching
var chug = require('gulp-chug'); // used to run external gulpfile in case of remote build
var merge = require('merge-stream'); // used to have multiple source in single task
var rename = require('gulp-rename'); // used to have multiple source in single task
var gulpVariables = require('./gulpVariables.json'); // external file that contains directory path and other variables for the build
const { src, dest, task, watch, series, parallel } = require('gulp');
// removes the old files from the directory so that we get a clean build each time
function clean() {
return deleteFiles([gulpVariables.dist, gulpVariables.clone, gulpVariables.codeReviewReportName]); // delete the directory
};
//task to clone from remote repo
function cloneRepo() {
return git.clone(gulpVariables.remoteRepoUrl,{args: './'+gulpVariables.clone}, function (err) {
if (err) throw err;
process.chdir(gulpVariables.clone);
});
};
//task to checkout branch in local repo cloned from remote
function checkoutRepo() {
return git.checkout(gulpVariables.repoBranchName, function (err) {
if (err) throw err;
process.chdir('..');
});
};
function runGulpfileInsideClone() {
return src(gulpVariables.clone+'/gulpfile.js',{read:false})
.pipe(chug());
};
//review all js files for error
function staticCodeReview() {
return src([
gulpVariables.src + '/*.js',
gulpVariables.apiSrc + '/*.js',
gulpVariables.jsSrc + '/*.js',
gulpVariables.jsSrc + '/**/*.js',
gulpVariables.schedulerSrc + '/*.js'
])
.pipe(jshint())
.pipe(jshint.reporter(jshintReporter, {
filename: gulpVariables.codeReviewReportName
})
);
};
//copy src files without the nodeserver.js and folders to dist
function copySourceFoldersWithoutJSFiles() {
//Pass in all files in the root w/ no subdirectories to dist
//dot:true to make sure to copy .cfignore file
//.cfignore contains files to ignore to deploy in bluemix
var source = src([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], {dot: true});
var destination = dest(gulpVariables.dist);
return source.pipe(destination);
};
// copy vendor css files to dist
function copyVendorCSSFiles() {
return src(gulpVariables.vendorCSSSrc + '/**/*.css')
.pipe(concat(gulpVariables.combinedVendorCSSFileName))
.pipe(dest(gulpVariables.cssDest));
};
copyVendorCSSFiles.description = 'copy vendor css files to dist';
// optimise vendor css files in dist
function optimiseVendorCSSFiles(done) {
if(gulpVariables.isOptimiseCSS) {
return src(gulpVariables.cssDest + '/' + gulpVariables.combinedVendorCSSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(cleancss())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(dest(gulpVariables.cssDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
}
else {
done();
}
};
optimiseVendorCSSFiles.description = 'optimise vendor css files in dist';
// copy vendor images to dist
function copyVendorImages() {
return src(gulpVariables.vendorImgSrc + '/**/*')
.pipe(dest(gulpVariables.imgDest));
};
// optimise vendor images in dist
function optimiseVendorImages(done) {
if(gulpVariables.isOptimiseImages) {
return src(gulpVariables.vendorImgDest)
.pipe(minifyImages())
.pipe(dest(gulpVariables.vendorImgDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
} else {
done();
}
};
// copy vendor js files to dist
function copyVendorJSFiles() {
var vendorJSWithoutPDFWorker = src([
gulpVariables.vendorJSSrc + '/**/angular.js', // this must be first
gulpVariables.vendorJSSrc + '/**/*.js', // all other files
'!' + gulpVariables.vendorJSSrc + '/**/pdf.worker.js'
])
.pipe(concat(gulpVariables.combinedVendorJSFileName))
.pipe(dest(gulpVariables.jsDest));
// ignoring the pdf.worker.js in the concatenated vendor file because for the PDF view it searches file with name pdf.worker.js
var PDFWorkerJS =src(gulpVariables.vendorJSSrc + '/vendor/pdf.worker.js')
.pipe(rename('vendor.min.worker.js'))
.pipe(dest(gulpVariables.jsDest));
return merge(vendorJSWithoutPDFWorker, PDFWorkerJS);
};
// optimise vendor js files in dist
function optimiseVendorJSFiles(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.jsDest + '/' + gulpVariables.combinedVendorJSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(uglify())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(dest(gulpVariables.jsDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
} else {
done();
}
};
// copy external css to dist
function copyCSSFiles() {
return src(gulpVariables.cssSrc + '/*.css')
.pipe(concat(gulpVariables.combinedAppCSSFileName))
.pipe(dest(gulpVariables.cssDest));
};
// optimise external css in dist
function optimiseCSSFiles(done) {
if(gulpVariables.isOptimiseCSS){
return src(gulpVariables.cssDest + '/' + gulpVariables.combinedAppCSSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(cleancss())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(dest(gulpVariables.cssDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
} else {
done();
}
};
// copy images to dist
function copyImages() {
return src(gulpVariables.imgSrc + '/*')
.pipe(dest(gulpVariables.imgDest));
};
// optimise images in dist
function optimiseImages(done) {
if(gulpVariables.isOptimiseImages){
return src(gulpVariables.imgDest + '/*')
.pipe(minifyImages())
.pipe(dest(gulpVariables.imgDest))
.pipe(gulpIf(gulpVariables.env == 'dev', liveReload()));
} else {
done();
}
};
// copy js files to dist
function copyJSFiles() {
return src([
gulpVariables.jsSrc + '/app.js', // this must be first
gulpVariables.jsSrc + '/**/*.js' // all other files
])
.pipe(concat(gulpVariables.combinedAppJSFileName))
.pipe(dest(gulpVariables.jsDest));
};
// optimise js files in dist
function optimiseJSFiles(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.jsDest + '/' + gulpVariables.combinedAppJSFileName)
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.init()))
.pipe(babel({
presets: ['es2015']
}))
.pipe(uglify())
.pipe(obfuscate())
.pipe(gulpIf(gulpVariables.env == 'dev',sourcemaps.write()))
.pipe(dest(gulpVariables.jsDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
} else {
done();
}
};
// copy nodeserver.js to dist
function copyNodeServerFile() {
return src(gulpVariables.src + '*.js')
.pipe(dest(gulpVariables.dist));
};
// optimise nodeserver.js in dist
function optimiseNodeServerFile(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.dist + '/*.js')
.pipe(gulpIf(gulpVariables.env == 'prod',babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod',uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod',obfuscate()))
.pipe(dest(gulpVariables.dist));
} else {
done();
}
};
// copy api files to dist
function copyApiFiles() {
return src(gulpVariables.apiSrc + '/**/*.js')
.pipe(dest(gulpVariables.apiDest));
};
// optimise api files in dist
function optimiseApiFiles(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.apiDest + '/**/*.js')
.pipe(cache())
.pipe(gulpIf(gulpVariables.env == 'prod',babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod', uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod', obfuscate()))
.pipe(dest(gulpVariables.apiDest));
} else {
done();
}
};
// copy mail templates to dist
function copyMailTemplates() {
return src(gulpVariables.mailTemplateSrc + '/**')
.pipe(dest(gulpVariables.mailTemplateDest));
};
// optimise mail templates in dist
function optimiseMailTemplates(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.mailTemplateDest + '/**')
.pipe(minifyejs())
.pipe(dest(gulpVariables.mailTemplateDest));
} else {
done();
}
};
// copy scheduler to dist
function copySchedulerFiles() {
return src(gulpVariables.schedulerSrc + '/*.js')
.pipe(dest(gulpVariables.schedulerDest));
};
// optimise scheduler in dist
function optimiseSchedulerFiles(done) {
if(gulpVariables.isOptimiseJS) {
return src(gulpVariables.schedulerDest + '/*.js')
.pipe(gulpIf(gulpVariables.env == 'prod', babel({
presets: ['es2015']
})))
.pipe(gulpIf(gulpVariables.env == 'prod', uglify()))
.pipe(gulpIf(gulpVariables.env == 'prod', obfuscate()))
.pipe(dest(gulpVariables.schedulerDest));
} else {
done();
}
};
// group all vendor copy tasks
const copyAndOptimiseVendorCSSFiles = parallel(copyVendorCSSFiles, optimiseVendorCSSFiles);
const copyAndOptimiseVendorImages = parallel(copyVendorImages, optimiseVendorImages);
const copyAndOptimiseVendorJSFiles = parallel(copyVendorJSFiles, optimiseVendorJSFiles);
const copyAndOptimiseVendorFiles = parallel(copyAndOptimiseVendorCSSFiles, copyAndOptimiseVendorImages, copyAndOptimiseVendorJSFiles);
const copyAndOptimiseCSSFiles = parallel(copyCSSFiles, optimiseCSSFiles);
const copyAndOptimiseImages = parallel(copyImages, optimiseImages);
// copy html files to dist
function copyHtmlFiles() {
return src(gulpVariables.htmlSrc + '/**')
.pipe(cache())
.pipe(dest(gulpVariables.htmlDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
const copyAndOptimiseJSFiles = parallel(copyJSFiles, optimiseJSFiles);
// group all client side app files copy tasks
const copyAndOptimiseClientSideAppFiles = parallel(copyAndOptimiseCSSFiles, copyAndOptimiseImages, copyHtmlFiles, copyAndOptimiseJSFiles);
const copyAndOptimiseNodeServerFile = parallel(copyNodeServerFile, optimiseNodeServerFile);
const copyAndOptimiseApiFiles = parallel(copyApiFiles, optimiseApiFiles);
const copyAndOptimiseMailTemplates = parallel(copyMailTemplates, optimiseMailTemplates);
const copyAndOptimiseSchedulerFiles = parallel(copySchedulerFiles, optimiseSchedulerFiles);
// group all server side app files copy tasks
const copyAndOptimiseServerSideAppFiles = parallel(copyAndOptimiseNodeServerFile, copyAndOptimiseApiFiles, copyAndOptimiseMailTemplates, copyAndOptimiseSchedulerFiles);
function copyCertificates(){
return src(gulpVariables.certSrc + '/*.*')
.pipe(dest(gulpVariables.certDest));
};
// copy index html file to dist
function injectIndexFile() {
var jsSrc,cssSrc,injectSrc;
jsSrc = [
gulpVariables.jsDest + '/vendor.min.js',
gulpVariables.jsDest + '/vendor.min.worker.js',
gulpVariables.jsDest + '/' + gulpVariables.combinedAppJSFileName
];
cssSrc = [
gulpVariables.cssDest + '/' + gulpVariables.combinedVendorCSSFileName,
gulpVariables.cssDest + '/' + gulpVariables.combinedAppCSSFileName
];
injectSrc = jsSrc.concat(cssSrc);
return src(gulpVariables.indexSrc + '/index.html')
.pipe(inject(src(injectSrc),
{ignorePath: 'dist/public', addRootSlash: false}
))
.pipe(dest(gulpVariables.indexDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
function injectIndexFileVanillaCopy() {
return src(gulpVariables.indexSrc + '/index.html')
.pipe(dest(gulpVariables.indexDest))
.pipe(gulpIf(gulpVariables.env == 'dev',liveReload()));
};
// nodemon to start the server
function node_server(done) {
if(gulpVariables.env == 'dev') {
nodemon({
script: gulpVariables.dist + '/' + gulpVariables.nodeServerFileName,
ext: 'js',
delay: "10000",
watch:[gulpVariables.apiDest, gulpVariables.dist + gulpVariables.nodeServerFileName, gulpVariables.schedulerDest],
done: done
});
} else {
done();
}
};
// Watch Files For Changes and calls the gulp task if any change happens
function watchFiles(done) {
if(gulpVariables.env == 'dev') {
liveReload.listen();
watch([gulpVariables.src + '*','!'+gulpVariables.src +'*.js'], series(copySourceFoldersWithoutJSFiles));
watch(gulpVariables.src + '*.js', series(copyAndOptimiseNodeServerFile));
watch(gulpVariables.apiSrc + '/**/*.js', series(copyAndOptimiseApiFiles));
watch(gulpVariables.mailTemplateSrc + '/**', series(copyAndOptimiseMailTemplates));
watch(gulpVariables.schedulerSrc + '/*.js', series(copyAndOptimiseSchedulerFiles));
watch(gulpVariables.cssSrc + '/*.css', series(copyAndOptimiseCSSFiles));
watch(gulpVariables.imgSrc + '/*', series(copyAndOptimiseImages));
watch(gulpVariables.htmlSrc + '/**', series(copyHtmlFiles));
watch(gulpVariables.jsSrc + '/**', series(copyAndOptimiseJSFiles));
watch(gulpVariables.indexSrc + '/index.html', series(injectIndexFileVanillaCopy));
watch(gulpVariables.vendorCSSSrc + '/**', series(copyAndOptimiseVendorCSSFiles));
watch(gulpVariables.vendorImgSrc + '/**', series(copyAndOptimiseVendorImages));
watch(gulpVariables.vendorJSSrc + '/**', series(copyAndOptimiseVendorJSFiles));
done();
}
};
/*
* Specify if tasks run in series or parallel using `series` and `parallel`
*/
const compile = series(clean, copySourceFoldersWithoutJSFiles, copyAndOptimiseVendorFiles, copyAndOptimiseClientSideAppFiles, copyAndOptimiseServerSideAppFiles, copyCertificates, injectIndexFileVanillaCopy) ;
const serve = series(compile, node_server);
serve.description = 'serve compiled source on local server at port 3000'
const watcher = parallel(serve, watchFiles)
//watcher.description = 'watch for changes to all source'
const defaultTasks = watcher;
/*
* You can use CommonJS `exports` module notation to declare tasks
*/
exports.clean = clean;
exports.cloneRepo = cloneRepo;
exports.staticCodeReview = staticCodeReview;
exports.checkoutRepo = checkoutRepo;
exports.copySourceFoldersWithoutJSFiles = copySourceFoldersWithoutJSFiles;
exports.copyVendorCSSFiles = copyVendorCSSFiles;
exports.optimiseVendorCSSFiles = optimiseVendorCSSFiles;
exports.copyAndOptimiseVendorCSSFiles = copyAndOptimiseVendorCSSFiles;
exports.copyVendorImages = copyVendorImages
exports.optimiseVendorImages = optimiseVendorImages;
exports.copyAndOptimiseVendorImages = copyAndOptimiseVendorImages;
exports.copyVendorJSFiles = copyVendorJSFiles;
exports.optimiseVendorJSFiles = optimiseVendorJSFiles;
exports.copyAndOptimiseVendorJSFiles = copyAndOptimiseVendorJSFiles;
exports.copyAndOptimiseVendorFiles = copyAndOptimiseVendorFiles;
exports.copyCSSFiles = copyCSSFiles;
exports.optimiseCSSFiles = optimiseCSSFiles;
exports.copyAndOptimiseCSSFiles = copyAndOptimiseCSSFiles;
exports.copyImages = copyImages;
exports.optimiseImages = optimiseImages;
exports.copyAndOptimiseImages = copyAndOptimiseImages
exports.copyHtmlFiles = copyHtmlFiles;
exports.copyJSFiles = copyJSFiles;
exports.optimiseJSFiles = optimiseJSFiles;
exports.copyAndOptimiseJSFiles = copyAndOptimiseJSFiles;
exports.copyAndOptimiseClientSideAppFiles = copyAndOptimiseClientSideAppFiles;
exports.copyNodeServerFile = copyNodeServerFile;
exports.optimiseNodeServerFile = optimiseNodeServerFile;
exports.copyAndOptimiseNodeServerFile = copyAndOptimiseNodeServerFile;
exports.copyApiFiles = copyApiFiles;
exports.optimiseApiFiles = optimiseApiFiles;
exports.copyAndOptimiseApiFiles = copyAndOptimiseApiFiles;
exports.copyMailTemplates = copyMailTemplates;
exports.optimiseMailTemplates = optimiseMailTemplates;
exports.copyAndOptimiseMailTemplates = copyAndOptimiseMailTemplates;
exports.copySchedulerFiles = copySchedulerFiles;
exports.optimiseSchedulerFiles = optimiseSchedulerFiles;
exports.copyAndOptimiseSchedulerFiles = copyAndOptimiseSchedulerFiles;
exports.copyAndOptimiseServerSideAppFiles = copyAndOptimiseServerSideAppFiles;
exports.copyCertificates = copyCertificates;
exports.injectIndexFileVanillaCopy = injectIndexFileVanillaCopy;
/*
* Define default task that can be called by just running `gulp` from cli
*/
exports.default = defaultTasks;