Gulp.js stops compiling LESS when watched after there has been an error in the LESS files
Asked Answered
A

4

11

I'm having a problem with gulp. I run gulp-watch along with gulp-less and gulp-clean. Everything is running perfectly.

When I edit somefile.less and I save it with a semi-colon missing or maybe I accidentally leave a trailing ;s, just have errors in my code when saving, gulp-less logs an error in the console. After I fix it gulp-watch continues watching the files, but gulp-less doesn't fire and it doesn't compile. When I stop gulp and run it again in the terminal everything goes back to normal.

Here is my gulpfile.js:

var gulp = require('gulp');
var clean = require('gulp-clean');
var gutil = require('gulp-util');
var less = require('gulp-less');
var watch = require('gulp-watch');
var path = require('path');

gulp.task('clean', function() {
    return gulp.src('src/main/webapp/styles/build', {read: false})
   .pipe(clean().on('error', gutil.log))
});

gulp.task('less', function() {
    return gulp.src(['src/main/webapp/styles/main.less'], {base: 'src/main/webapp/styles/'})
    .pipe(less().on('error', gutil.log))
    .pipe(gulp.dest('src/main/webapp/styles/build'))
    .on('error', gutil.log);
});

gulp.task('watch', function() {
    watch('src/main/webapp/styles/**/*.{less, css}', function() {
        gulp.start('less')
        .on('error', gutil.log);
    })
});

gulp.task('default', ['clean'], function() {
    gulp.start(['less', 'watch'])
    .on('error', gutil.log);
});

And here are my devDependencies:

"devDependencies": {
    "gulp": "^3.8.10",
    "gulp-clean": "^0.3.1",
    "gulp-less": "^2.0.1",
    "gulp-util": "^3.0.2",
    "gulp-watch": "^3.0.0"
}

Finally, here is the message in the console:

[10:21:03] imports/productSearchPage.less was changed
[10:21:03] Starting 'less'...
[10:21:03] { [Error: Unrecognised input. Possibly missing something in file /src/main/webapp/styles/imports/productSearchPage.less line no. 1008]
  type: 'Parse',
  filename: '/src/main/webapp/styles/imports/productSearchPage.less',
  index: 19127,
  line: 1008,
  callLine: NaN,
  callExtract: undefined,
  column: 0,
  extract: [ '', '', undefined ],
  message: 'Unrecognised input. Possibly missing something in file /src/main/webapp/styles/imports/productSearchPage.less line no. 1008',
  stack: undefined,
  lineNumber: 1008,
  fileName: '/src/main/webapp/styles/imports/productSearchPage.less',
  name: 'Error',
  showStack: false,
  showProperties: true,
  plugin: 'gulp-less',
  __safety: { toString: [Function] } }
[10:21:04] imports/productSearchPage.less was changed
[10:21:08] imports/productSearchPage.less was changed
^C

Can you please tell me what is wrong with the gulp-watch task and help me make it run gulp-less after the errors have been removed, without restarting gulp.

EDIT: My edited gulp-less task

gulp.task('less', function() {
    return gulp.src(['src/main/webapp/styles/main.less'], {base: 'src/main/webapp/styles/'})
    .pipe(less().on('error', gutil.log))
    .pipe(gulp.dest('src/main/webapp/styles/build'))
    .on('error', function(err) {
        gutil.log(err);
        this.emit('end');
    });
});
Abdomen answered 27/1, 2015 at 8:51 Comment(0)
A
22

It works now! Here is my final, and working, gulp-less task:

gulp.task('less', function() {
    return gulp.src(['src/main/webapp/styles/main.less'], {base: 'src/main/webapp/styles/'})
    .pipe(less().on('error', function(err){
        gutil.log(err);
        this.emit('end');
    }))
    .pipe(gulp.dest('src/main/webapp/styles/build'))
});

The problem was that, when there was an error in the LESS the task still went on and built the destination file. On top of that I placed the error logging function and the emit('end') as a callback to gulp.dest.

Now, when the callback of less() is the error log and emit('end') everything works perfectly.

Abdomen answered 28/1, 2015 at 14:24 Comment(1)
This bit got the less to rewatch for me this.emit('end'). Thanks for your post!Bruner
H
2

I always use gulp-plumber for my error catching. Works really easily and logs the error to the console.

Example:

gulp.task('less', function() {
    return gulp.src(['src/main/webapp/styles/main.less'], {base: 'src/main/webapp/styles/'})
    .pipe(plumber())
    .pipe(less().on('error', gutil.log))
    .pipe(gulp.dest('src/main/webapp/styles/build'))
    .on('error', function(err) {
        gutil.log(err);
        this.emit('end');
    });
});
Halifax answered 27/1, 2015 at 11:28 Comment(1)
I use this too. It catches errors in the stream, before they have a chance to break it.Katleen
K
0

I have just set this up for my own personal project. According to the Gulp docs, you can just use gulp.watch:

gulp.task('watch', function() {
    gulp.watch('src/main/webapp/styles/**/*.{less, css}', ['less'])
        .on('error', gutil.log);
});

EDIT: If this doesn't help, change your less task to:

gulp.task('less', function() {
    return gulp.src(['src/main/webapp/styles/main.less'], {base: 'src/main/webapp/styles/'})
    .pipe(less())
    .on('error', function (err) {
        gutil.log(err);
        this.emit('end');
    })
    .pipe(gulp.dest('src/main/webapp/styles/build'))
    .on('error', gutil.log);
});

Adapted from this comment.

Kaftan answered 27/1, 2015 at 8:59 Comment(12)
If this answer works, my answer was adapted from this question: #21906375Kaftan
The problem stays. Also, gulp-util doesn't log the error to the console.Abdomen
@PavelKuts - I think I've found your problem. See my updated answer.Kaftan
See my edited question to see my new gulp task. gulp-less now works after the error, but the error isn't logged to the console.Abdomen
Your edited file doesn't contain my suggestion - what has changed?Kaftan
I added this.emit(end);Abdomen
You have a double closing parenthesis. Besides that, the code doesn't log errors to the console, gulp-less works after there has been an error and is edited. It still doesn't work.Abdomen
Oops! Made one more minor change: should be this.emit('end'), with the 'end' being a string.Kaftan
I will mark the answer as correct, as it does run the gulp-less task after there has been an error. But it would be nice to see a resolution where the errors are logged to the console. With the current code there are no logs.Abdomen
Yeah, that's weird. I'm using almost identical code in one of my projects and I get all the logs... I hope you figure it out - good luck! :)Kaftan
I figured it out, not without help from you! Check the edit in my question to see where I was failing, and hopefully you can use the code in the future. Cheers!Abdomen
Ah, yes! Should've made it clearer - your .on('error'...) needs to come immediately after the .pipe(less()). Glad to hear you sorted it out!Kaftan
T
0

the best solution I have tried; https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md

var combiner = require('stream-combiner2');
gulp.task('multi:less', function(done) {
    var combined = combiner.obj([
        gulp.src(srcs),
        less(),
        autoprefixer({
            browsers: ['last 6 versions'],
            cascade: false
        }),
        isDev ? null : cleanCss(),
        gulp.dest(targetDir + 'css/multi/'),
    ].filter(v => v));

    // any errors in the above streams will get caught
    // by this listener, instead of being thrown:
    combined.on('error', console.error.bind(console));
    combined.on('end', () => {}); //done have been call when return combined;
    return combined;

}
Trumaine answered 6/2, 2017 at 12:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.