Use gulp-plumber on sass task - gulp

Whenever there's an error in my .scss file, my gulp task stops and I have to run gulp in the Terminal again. I'm trying to use gulp-plumber to remedy this, but can't work out where to place it in the task.
I'm requiring it like this, at the top of my gulpfile:
var gulp = require('gulp'),
sass = require('gulp-sass'),
plumber = require('gulp-plumber'),
...
I'm trying to pipe it into the task like so:
gulp.task('pre-process', function(){
gulp.src('./sass/mnml.scss')
.pipe(plumber())
.pipe(watch(function(files) {
return files.pipe(sass())
.pipe(prefix())
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('css'))
.pipe(minifyCSS())
.pipe(rename('mnml.min.css'))
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('./css/'))
.pipe(browserSync.reload({stream:true}));
}));
});
But when I run gulp, I get this error:
stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: /Users/realph/Dropbox/temp/mnml/sass/base:4: error: unbound variable $b-color
Any idea what I'm doing wrong? Any help is appreciated. Thanks in advance!

You're creating another stream of files in the watch callback, and I don't think it's using the top plumber plugin.
To do so, you have to change your callback to use it like:
return files
.pipe(plumber())
.pipe(sass())
.pipe(prefix())
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('css'))
.pipe(minifyCSS())
.pipe(rename('mnml.min.css'))
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('./css/'))
.pipe(browserSync.reload({stream:true}));
You can also specify the errLogToConsole to your sass pipe
.pipe(sass({ errLogToConsole: true }))

Related

Running a Gulp Task inside the Watch Task

I have the following Gulp Watch Task.
// Watch function
function watch() {
// browserSync.init({
// proxy: 'localhost/Unice/html'
// });
gulp.watch('assets/scss/**.*scss', style);
gulp.watch('./*.html').on('change', browserSync.reload);
gulp.watch('assets/css/**.css').on('change', browserSync.reload);
}
I have another task which converts SCSS to css as follows
//scss to css
function style() {
return gulp.src('assets/scss/**/*.scss', { sourcemaps: true })
.pipe(sass({
outputStyle: 'compressed'
}).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(gulp.dest('assets/css', { sourcemaps: '.' }))
.pipe(browserSync.reload({ stream: true }));
}
How can I run the style task automatically when running the watch command if I make modifications to any SCSS files.
The glob in your watch task contains an error and should be:
gulp.watch('assets/scss/**/*.scss', style);

Gulp compile less files and minify them

I'm new in the use of task runners like Gulp or Grunt, I have chosen to use Gulp to automate my tasks because I'm familiar with Javascript language.
I succeeded to compile my .less files to .css, I even wrote a task to minify my .css files.
I would like to run watch task with BrowSync, which automatically compile .less files to .css and .css to .min.css.
Here's my code :
gulp.task('minifyCSS', () => {
return gulp.src([
'web/assets/css/*.css',
'!web/assets/css/*.min.css'
])
.pipe(sourcemaps.init())
.pipe(cleanCSS())
.pipe(sourcemaps.write())
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('web/assets/css'));});
gulp.task('less', () => {
return gulp.src('web/assets/less/*.less')
.pipe(less())
.pipe(gulp.dest('web/assets/css'))
.pipe(browserSync.reload({
stream: true
}));});
gulp.task('watchSync', ['less', 'minifyCSS', 'browserSync'] , () => {
gulp.watch('web/assets/less/*.less', ['less']);
});
gulp.task('browserSync', () => {
browserSync.init({
notify: false,
browser: "chrome",
proxy: "localhost/web/app_dev.php",
open: false
});});
The browserSync task runs well but it never compiles .css to .min.css. But when I run "gulp minifyCSS" it does the job ...
Do I miss a step ? Can anyone help me on this one ? :)
I'm nearly sure this will work:
gulp.task('minifyCSS', ['less'], () => {
return gulp.src([
'web/assets/css/*.css',
'!web/assets/css/*.min.css'
])
.pipe(sourcemaps.init())
.pipe(cleanCSS())
.pipe(sourcemaps.write())
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('web/assets/css'))
.pipe(browserSync.reload({
stream: true
}))
;
});
gulp.task('less', () => {
return gulp.src('web/assets/less/*.less')
.pipe(less())
.pipe(gulp.dest('web/assets/css'))
;
});
gulp.task('watchSync', ['minifyCSS', 'browserSync'] , () => {
gulp.watch('web/assets/less/*.less', ['minifyCSS']);
});
gulp.task('browserSync', () => {
browserSync.init({
notify: false,
browser: "chrome",
proxy: "localhost/web/app_dev.php",
open: false
});
});

How to bundle external dependencies using gulp

I'm trying to bundle external commonjs modules (react, react-dom) together with some plain ES5 files, like pollyfills.js.
I can bundle the external modules using browserify.require
var externalBundler = browserify();
config.externalModules.forEach(externalBundler.bundle);
return externalBundler.bundle()
.pipe(source("external.js"))
.pipe(buffer())
.pipe(sourcemaps.init({ debug: true, loadMaps: true }))
.pipe(uglify())
.on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/'));
and the other scripts using gulp.concat, however I struggle to put them toggether.
I was able to combine the pipes like this:
gulp.task('bundle-externalscripts', function () {
var externalBundler = browserify({ debug: true });
for (var module of config.externalModules) externalBundler.require(module);
var globalScripts = gulp.src(paths.scripts);
var externalModules = externalBundler.bundle()
.pipe(source("externalmodules.js")) //always convert to vinyl source stream
.pipe(buffer()); //in buffered mode
return merge(globalScripts, externalModules)
.pipe(sourcemaps.init({ debug: true, loadMaps: true }))
.pipe(concat("external.js"))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/'));
});

Gulp watch not recognised as function

This is a full gulp js file. Here gulp-watch is not used. So it's commented.
gulp.task('scripts', function() {
gulp.src(['app/*.js', 'app/shared/*/*.js','app/components/*/*.js'])
.pipe(plumber({
handleError: function(err) {
console.log(err);
this.emit('end');
}
}))
// .pipe(watch(['app/*.js', 'app/shared/*/*.js','app/components/*/*.js']))
.pipe(print(function(filepath) {
return "MrGopal modified : " + filepath;
}))
.pipe(ngAnnotate())
.pipe(concate('zaya.app.js'))
.pipe(rename({
suffix: '.min'
}))
.pipe(uglify())
.pipe(gulp.dest('assets/js'))
.pipe(broswerSync.stream())
})
Browser sync TASK
gulp.task('browser-sync', function() {
broswerSync.init({
notify: true,
proxy: "http://localhost:8000"
})
})
gulp.task('scripts-sync',['scripts'],broswerSync.reload)
gulp.task('html-sync',['html'],broswerSync.reload)
gulp.task('less-sync',['less'],broswerSync.reload)
WATCH TASK
gulp.watch(['app/*.js', 'app/shared/*/*.js', 'app/components/*/*.js'], ['scripts','scripts-sync']);
gulp.watch(['app/shared/*/*.html','app/components/*/*.html'], ['html','html-sync']);
gulp.watch(['app/shared/*/*.css','app/components/*/*.css'], ['less','less-sync']);
DEFAULT TASK
gulp.task('default', ['scripts', 'html', 'less', 'watch','browser-sync'])
While running gulp, it says watch is not a function. But same code works at my office. What could be wrong?
The error code :
[16:03:49] 'watch' errored after 244 μs
[16:03:49] TypeError: undefined is not a function
at Gulp.watch (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/gulp/index.js:35:16)
at Gulp.<anonymous> (/home/gopal/Documents/zaya-proto/zaya/zaya/static/gulpfile.js:96:10)
at module.exports (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/index.js:214:10)
at /home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/index.js:279:18
at finish (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/lib/runTask.js:21:8)
at module.exports (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/lib/runTask.js:60:3)
at Gulp.Orchestrator._runTask (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep (/home/gopal/Documents/zaya-proto/zaya/zaya/static/node_modules/orchestrator/index.js:214:10)

Watch task not continuing after error caught by Gulp-plumber has been fixed despite errorHandler callback

So I got this neat gulpfile and all, and it's working smoothly except for this one thing.
I'm running gulp-plumber to stop the watch task from crashing on an error, the error is getting caught by it but then when I fix the error, the watcher refuse to continue. I added the handleError callback but it doesn't appear to do anything even though this article says that it should. This is driving me to insanity because I know people who has gotten it working without any of these but none of the solutions I've found seems to work. Have I missed something?
EDIT: When I have an error in _lists.scss for example the error thrown looks like this:
[22:04:43] Plumber found unhandled error:
Error in plugin 'gulp-sass'
Message:
styles\partials\_lists.scss
1:1 invalid top-level expression
Does this mean that I also have to handle the error manually using on.('error', function() {})? Because I thought this was plumber purpose, to remove the manual error handling. I even tried manually catching the error using this but it just spit out the error in the console and refused to continue just like before.
Here's the plumber pipe part:
// Compile our SCSS into minified CSS
gulp.task('styles', function() {
return gulp.src('styles/main.scss')
.pipe(plumber({
handleError: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sass({ style: 'expanded' }))
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('dist/styles'))
.pipe(rename({ suffix: '.min' }))
.pipe(minifycss())
.pipe(gulp.dest('dist/styles'))
.pipe(notify({ message: 'Finished compiling SCSS' }))
});
And here's the whole gulpfile.js:
var gulp = require('gulp'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
minifycss = require('gulp-minify-css'),
plumber = require('gulp-plumber'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
livereload = require('gulp-livereload'),
htmlmin = require('gulp-htmlmin'),
del = require('del');
// Minify our HTML
gulp.task('html', function() {
return gulp.src('*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('dist'))
});
// Compile our SCSS into minified CSS
gulp.task('styles', function() {
return gulp.src('styles/main.scss')
.pipe(plumber({
handleError: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sass({ style: 'expanded' }))
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('dist/styles'))
.pipe(rename({ suffix: '.min' }))
.pipe(minifycss())
.pipe(gulp.dest('dist/styles'))
.pipe(notify({ message: 'Finished compiling SCSS' }))
});
// Concat and compile our JS into a minified file
gulp.task('scripts', function() {
return gulp.src('scripts/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(concat('main.js'))
.pipe(gulp.dest('dist/scripts'))
.pipe(rename({ suffix: '.min' }))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts'))
.pipe(notify({ message: 'Finished compiling scripts' }));
});
// Compress our images
gulp.task('images', function() {
return gulp.src('images/**/*.js')
.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
.pipe(gulp.dest('dist/images'))
.pipe(notify({ message: 'Finished compiling images' }));
});
// Clean/empty our dist folder
gulp.task('clean', function(cb) {
del(['dist/styles', 'dist/scripts', 'dist/images'], cb)
});
// Run all our tasks when using 'gulp' command in CLI
gulp.task('default', ['clean'], function() {
gulp.start('html', 'styles', 'scripts', 'images');
});
// Watch our files for changes
gulp.task('watch', function() {
gulp.watch('styles/**/*.scss', ['styles']);
gulp.watch('scripts/**/*.js', ['scripts']);
gulp.watch('images/**/*', ['images']);
});
It might be just a typo.
Try replacing handleError with errorHandler.
Exact same issue, just worked it out. The charm is to add
this.emit('end');
at the end of your handler to gracefully end the task.