Prevent errors from breaking / crashing gulp watch

后端 未结 8 883
我在风中等你
我在风中等你 2020-12-12 09:17

I\'m running gulp 3.6.2 and have the following task that was set up from a sample online

gulp.task(\'watch\', [\'default\'], function () {
  gulp.watch([
            


        
8条回答
  •  失恋的感觉
    2020-12-12 09:42

    With one format of files

    (ex: *.coffee only)

    If you want to work only with one format of files, then gulp-plumber is your solution.

    For example rich handled errors and warning for coffeescripting:

    gulp.task('scripts', function() {
      return gulp.src(['assets/scripts/**/*.coffee'])
        .pipe(plumber())
        .pipe(coffeelint())
        .pipe(coffeelint.reporter())
        .pipe(lintThreshold(10, 0, lintThresholdHandler))
        .pipe(coffee({
          bare: true
        }))
        .on('error', swallowError)
        .pipe(concat('application.js'))
        .pipe(gulp.dest('dist/scripts'))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(gulp.dest('dist/scripts'))
        .pipe(notify({ message: 'Scripts task complete' }));
    });
    

    With multiple types of file formats

    (ex: *.coffee and *.js at same time)

    But if you won't to work with multiple types of file formats (for example: *.js and *.coffee), than i will post my solution.

    I will just post a self explanatory code over here, with some description before.

    gulp.task('scripts', function() {
      // plumber don't fetch errors inside gulpif(.., coffee(...)) while in watch process
      return gulp.src(['assets/scripts/**/*.js', 'assets/scripts/**/*.coffee'])
        .pipe(plumber())
        .pipe(gulpif(/[.]coffee$/, coffeelint()))
        .pipe(coffeelint.reporter())
        .pipe(lintThreshold(10, 0, lintThresholdHandler))
        .pipe(gulpif(/[.]coffee$/, coffee({ // if some error occurs on this step, plumber won't catch it
          bare: true
        })))
        .on('error', swallowError)
        .pipe(concat('application.js'))
        .pipe(gulp.dest('dist/scripts'))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(gulp.dest('dist/scripts'))
        .pipe(notify({ message: 'Scripts task complete' }));
    });
    

    I faced the issue with gulp-plumber and gulp-if using gulp.watch(...

    See related issue here: https://github.com/floatdrop/gulp-plumber/issues/23

    So the best option for me was:

    • Each part as file, and concatenate after. Create multiple tasks that can process each part in separate file (like grunt does), and concatenate them
    • Each part as stream, and merge streams after. Merge two streams using merge-stream (that was made from event-stream) into one and continue the job (i tried that first, and it work fine for me, so it is faster solution than previous one)

    Each part as stream, and merge streams after

    Her is the main part of my code:

    gulp.task('scripts', function() {
      coffeed = gulp.src(['assets/scripts/**/*.coffee'])
        .pipe(plumber())
        .pipe(coffeelint())
        .pipe(coffeelint.reporter())
        .pipe(lintThreshold(10, 0, lintThresholdHandler))
        .pipe(coffee({
          bare: true
        }))
        .on('error', swallowError);
    
      jsfiles = gulp.src(['assets/scripts/**/*.js']);
    
      return merge([jsfiles, coffeed])
        .pipe(concat('application.js'))
        .pipe(gulp.dest('dist/scripts'))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(gulp.dest('dist/scripts'))
        .pipe(notify({ message: 'Scripts task complete' }));
    });
    

    Each part as file, and concatenate after

    If to separate this into parts, then in each part there should be a result file created. For ex.:

    gulp.task('scripts-coffee', function() {
    
      return gulp.src(['assets/scripts/**/*.coffee'])
        .pipe(plumber())
        .pipe(coffeelint())
        .pipe(coffeelint.reporter())
        .pipe(lintThreshold(10, 0, lintThresholdHandler))
        .pipe(coffee({
          bare: true
        }))
        .on('error', swallowError)
        .pipe(concat('application-coffee.js'))
        .pipe(gulp.dest('dist/scripts'));
    
    });
    
    gulp.task('scripts-js', function() {
    
      return gulp.src(['assets/scripts/**/*.js'])
        .pipe(concat('application-coffee.js'))
        .pipe(gulp.dest('dist/scripts'));
    
    });
    
    gulp.task('scripts', ['scripts-js', 'scripts-coffee'], function() {
    
      var re = gulp.src([
        'dist/scripts/application-js.js', 'dist/scripts/application-coffee.js'
      ])
        .pipe(concat('application.js'))
        .pipe(gulp.dest('dist/scripts'))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(gulp.dest('dist/scripts'))
        .pipe(notify({ message: 'Scripts task complete' }));
    
      del(['dist/scripts/application-js.js', 'dist/scripts/application-coffee.js']);
    
      return re;
    
    });
    

    P.S.:

    Here node modules and functions that were used:

    // Load plugins
    var gulp = require('gulp'),
        uglify = require('gulp-uglify'),
        rename = require('gulp-rename'),
        concat = require('gulp-concat'),
        notify = require('gulp-notify'),
        plumber = require('gulp-plumber'),
        merge = require('ordered-merge-stream'),
        replace = require('gulp-replace'),
        del = require('del'),
        gulpif = require('gulp-if'),
        gulputil = require('gulp-util'),
        coffee = require('gulp-coffee'),
        coffeelint = require('gulp-coffeelint),
        lintThreshold = require('gulp-coffeelint-threshold');
    
    var lintThresholdHandler = function(numberOfWarnings, numberOfErrors) {
      var msg;
      gulputil.beep();
      msg = 'CoffeeLint failure; see above. Warning count: ';
      msg += numberOfWarnings;
      msg += '. Error count: ' + numberOfErrors + '.';
      gulputil.log(msg);
    };
    var swallowError = function(err) {
      gulputil.log(err.toString());
      this.emit('end');
    };
    

提交回复
热议问题