I have a problem with gulp watch that breaking after error. Then i found a good reference to use plumber, and the extension of it, gulp-prettyerror.
Then i create this gulpfile.js
const gulp = require('gulp'),
babel = require('gulp-babel')
changed = require('gulp-changed'),
prettyError = require('gulp-prettyerror');
////////////////////////// START SQUAREBOOK ////////////////////////////////
const reactSquarebookSource = './common/modules/squarebook/web/jsx/*.{js,jsx}';
const reactSquarebookDest = './common/modules/squarebook/web/js';
// run babel on squarebook
gulp.task('babel:squarebook', function () {
return gulp.src(reactSquarebookSource)
.pipe(prettyError())
.pipe(changed(reactSquarebookDest)) // make sure only changed source
.pipe(babel()) // do the babel
.pipe(gulp.dest(reactSquarebookDest));
});
gulp.task('watch:squarebook', function () {
gulp.watch(reactSquarebookSource, ['babel:squarebook']);
});
////////////////////////// FINISH SQUAREBOOK ///////////////////////////////
///////////////////////// START FRONTEND ///////////////////////////////////
const reactFrontendSource = './frontend/web/jsx/*.{js,jsx}';
const reactFrontendDest = './frontend/web/js';
// run babel on frontend
gulp.task('babel:frontend', function () {
return gulp.src(reactFrontendSource)
.pipe(prettyError())
.pipe(changed(reactFrontendDest)) // make sure only changed source
.pipe(babel()) // do the babel
.pipe(gulp.dest(reactFrontendDest));
});
gulp.task('watch:frontend', function () {
gulp.watch(reactFrontendSource, ['babel:frontend']);
});
///////////////////////// FINISH FRONTEND //////////////////////////////////
// all babel react
gulp.task('babel', [
'babel:squarebook',
'babel:frontend'
])
// all watchers
gulp.task('watch', [
'watch:squarebook',
'watch:frontend'
]);
gulp.task('default', [
'babel',
'watch'
]);
The prettyError works really fine. I like that. But this code is pretty redundant. I still need to create more modules, which will make me copy-paste the task each time i create a module. So i decided to refactor it to:
// require all the libraries
const gulp = require('gulp'),
babel = require('gulp-babel')
changed = require('gulp-changed'),
prettyError = require('gulp-prettyerror');
// react source map
const moduleSources = {
squarebook: {
src : './common/modules/squarebook/web/jsx/*.{js,jsx}',
dest : './common/modules/squarebook/web/js'
},
frontend: {
src : './frontend/web/jsx/*.{js,jsx}',
dest : './frontend/web/js'
}
}
gulp.task('babel', function () {
for(var moduleName in moduleSources) {
var sourceMap = moduleSources[moduleName];
var taskName = 'babel:' + moduleName;
// create the task
gulp.task(taskName, function () {
return gulp.src(sourceMap.src)
.pipe(changed(sourceMap.dest)) // make sure only changed source
.pipe(prettyError())
.pipe(babel()) // do the babel
.pipe(gulp.dest(sourceMap.dest));
});
// do the watcher
gulp.watch(sourceMap.src, [taskName]);
}
});
gulp.task('default', [
'babel'
]);
Now that i have tried to create an error on the './common/modules/squarebook/web/jsx/*.{js,jsx}'
, the error is not displayed. It seems that prettyError only shows the error in the last loop. The watcher is not breaking, but the error is not displayed. Any idea why this is happening?
I wonder whether the loop is making the error or not.
The problem is that i use sourceMap
inside the anonymous function, that will be updated until the end of the loop. So, my solution is:
// require all the libraries
const gulp = require('gulp'),
babel = require('gulp-babel')
changed = require('gulp-changed'),
prettyError = require('gulp-prettyerror');
// react source map
const moduleSources = {
squarebook: {
src : './common/modules/squarebook/web/jsx/*.{js,jsx}',
dest : './common/modules/squarebook/web/js'
},
frontend: {
src : './frontend/web/jsx/*.{js,jsx}',
dest : './frontend/web/js'
}
}
// http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
// create function to ensure the right closure
function processBabel(src, dest) {
console.log(src);
return gulp.src(src)
.pipe(changed(dest)) // make sure only changed source
.pipe(prettyError())
.pipe(babel()) // do the babel
.pipe(gulp.dest(dest));
}
var babelTasks = [];
gulp.task('babel', function () {
for(var moduleName in moduleSources) {
var sourceMap = moduleSources[moduleName];
var taskName = 'babel:' + moduleName;
// create the task
gulp.task(taskName, processBabel.bind(this, sourceMap.src, sourceMap.dest));
// do the watcher
gulp.watch(sourceMap.src, [taskName]);
}
});
gulp.task('default', [
'babel'
]);
Therefore, i create other function to handle src
and dest
, so that it will not be updated by reference.