Предотвратить ошибки от поломки / сбои залпом смотреть


я запускаю gulp 3.6.2 и имею следующую задачу, которая была настроена из образца онлайн

gulp.task('watch', ['default'], function () {
  gulp.watch([
    'views/**/*.html',        
    'public/**/*.js',
    'public/**/*.css'        
  ], function (event) {
    return gulp.src(event.path)
      .pipe(refresh(lrserver));
  });

  gulp.watch(['./app/**/*.coffee'],['scripts']);
  gulp.watch('./app/**/*.scss',['scss']);
});

каждый раз, когда есть ошибка в моем CoffeeScript gulp watch останавливается - очевидно, не то, что я хочу.

как рекомендовано в другом месте я попробовал это

gulp.watch(['./app/**/*.coffee'],['scripts']).on('error', swallowError);
gulp.watch('./app/**/*.scss',['scss']).on('error', swallowError);
function swallowError (error) { error.end(); }

но это, кажется, не работает.

что я делаю не так?


в ответ на ответ @Aperçu я изменил мой swallowError метод и попробовал вместо этого следует:

gulp.task('scripts', function () {
  gulp.src('./app/script/*.coffee')
    .pipe(coffee({ bare: true }))
    .pipe(gulp.dest('./public/js'))
    .on('error', swallowError);
});

перезапущен, а затем создал синтаксическую ошибку в моем файле кофе. Тот же вопрос:

[gulp] Finished 'scripts' after 306 μs

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: W:bariokartappscripttrishell.coffee:5:1: error: unexpected *
*
^
  at Stream.modifyFile (W:bariokartnode_modulesgulp-coffeeindex.js:37:33)
  at Stream.stream.write (W:bariokartnode_modulesgulp-coffeenode_modulesevent-streamnode_modulesthroughindex.js:26:11)
  at Stream.ondata (stream.js:51:26)
  at Stream.EventEmitter.emit (events.js:95:17)
  at queueData (W:bariokartnode_modulesgulpnode_modulesvinyl-fsnode_modulesmap-streamindex.js:43:21)
  at next (W:bariokartnode_modulesgulpnode_modulesvinyl-fsnode_modulesmap-streamindex.js:71:7)
  at W:bariokartnode_modulesgulpnode_modulesvinyl-fsnode_modulesmap-streamindex.js:85:7
  at W:bariokartnode_modulesgulpnode_modulesvinyl-fslibsrcbufferFile.js:8:5
  at fs.js:266:14
  at W:bariokartnode_modulesgulpnode_modulesvinyl-fsnode_modulesgraceful-fsgraceful-fs.js:104:5
  at Object.oncomplete (fs.js:107:15)
9 164

9 ответов:

код

приведенные выше примеры не работают для меня. Однако было сделано следующее:

var plumber = require('gulp-plumber');
var liveReload = require('gulp-livereload');
var gutil = require('gulp-util');
var plumber = require('gulp-plumber');
var compass = require('gulp-compass');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');
var notify = require('gulp-notify');

gulp.task('styles', function () {
    //only process main.scss which imports all other required styles - including vendor files.
    return gulp.src('./assets/scss/main.scss')
            .pipe(plumber(function (error) {
                gutil.log(error.message);
                this.emit('end');
            }))
            .pipe(compass({
                config_file: './config.rb',
                css: './css'
                , sass: './assets/scss'
            }))
            //minify files
            .pipe(rename({suffix: '.min'}))
            .pipe(minifycss())

            //output
            .pipe(gulp.dest('./css'))
            .pipe(notify({message: 'Styles task complete'}));
});

gulp.task('watch', function () {
    liveReload.listen();
    gulp.watch('assets/scss/**/*.scss', ['styles']);
});

С одним форматом файлов

(пример: *.только кофе)

если вы хотите работать только с одним форматом файлов, то gulp-plumber - это ваше решение.

например Рич обработал ошибки и предупреждение для 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' }));
});

С несколькими типами форматов файлов

(пример: *.кофе и.* js в то же время)

но если вы не хотите работать с несколькими типами форматов файлов (например: *.js и *.coffee), чем я выложу свое решение.

я просто опубликую здесь пояснительный код с некоторым описанием раньше.

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' }));
});

я столкнулся с проблемой с gulp-plumber и gulp-if используя gulp.watch(...

смотрите соответствующий вопрос здесь:https://github.com/floatdrop/gulp-plumber/issues/23

поэтому лучшим вариантом для меня было:

  • каждая часть как файл, и сцепить после. Создайте несколько задач, которые могут обрабатывать каждую часть в отдельном файле (например, grunt) и объединять их
  • каждая часть как поток, и объединить потоки после. Слияние двух потоков с помощью merge-stream (это было сделано из event-stream) в один и продолжить работу (я попробовал, что первый, и он отлично работает для меня, так что это быстрее решение, чем предыдущий)

каждая часть как поток, и объединить потоки после

ее основная часть моего кода:

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' }));
});

каждая часть как файл, и добавил после

если разделить это на части, затем в каждой части должен быть создан файл. Например.:

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;

});

П. С.:

здесь узлы модулей и функций, которые были использованы:

// 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');
};

я реализовал следующий хак в качестве обходного пути для https://github.com/gulpjs/gulp/issues/71:

// Workaround for https://github.com/gulpjs/gulp/issues/71
var origSrc = gulp.src;
gulp.src = function () {
    return fixPipe(origSrc.apply(this, arguments));
};
function fixPipe(stream) {
    var origPipe = stream.pipe;
    stream.pipe = function (dest) {
        arguments[0] = dest.on('error', function (error) {
            var state = dest._readableState,
                pipesCount = state.pipesCount,
                pipes = state.pipes;
            if (pipesCount === 1) {
                pipes.emit('error', error);
            } else if (pipesCount > 1) {
                pipes.forEach(function (pipe) {
                    pipe.emit('error', error);
                });
            } else if (dest.listeners('error').length === 1) {
                throw error;
            }
        });
        return fixPipe(origPipe.apply(this, arguments));
    };
    return stream;
}

добавьте его в свой файл глотка.js и использовать его так:

gulp.src(src)
    // ...
    .pipe(uglify({compress: {}}))
    .pipe(gulp.dest('./dist'))
    .on('error', function (error) {
        console.error('' + error);
    });

Это кажется мне самой естественной обработкой ошибок. Если нет обработчика ошибок вообще, он будет выдавать ошибку. Протестировано с узлом v0.11.13.

простое решение этой проблемы-поставить gulp watch в бесконечном цикле внутри оболочки Bash (или sh).

while true; do gulp; gulp watch; sleep 1; done

держите вывод этой команды в видимой области на экране при редактировании JavaScript. Когда ваши изменения приведут к ошибке, Gulp выйдет из строя, распечатает свою трассировку стека, подождет секунду и возобновит просмотр исходных файлов. Затем вы можете исправить синтаксическую ошибку, и Gulp укажет, было ли редактирование успешным, либо распечатав это нормальный выход или сбой (затем возобновление) снова.

это будет работать в терминале Linux или Mac. Если вы используете Windows, используйте Cygwin или Ubuntu Bash (Windows 10).

Typescript

это то, что сработало для меня. Я работаю с Typescript и отделил функцию (к путанице aovid с this ключевое слово) для обработки less. Это работает с Javascript как хорошо.

var gulp = require('gulp');
var less = require('gulp-less');

gulp.task('less', function() {
    // writing a function to avoid confusion of 'this'
    var l = less({});
    l.on('error', function(err) {
        // *****
        // Handle the error as you like
        // *****
        l.emit('end');
    });

    return gulp
        .src('path/to/.less')
        .pipe(l)
        .pipe(gulp.dest('path/to/css/output/dir'))
})

теперь, когда вы watch.less файлы и error происходит watch не остановится и новые изменения будут обработаны в соответствии с вашим less task.

Примечание: я пробовал с l.end();; однако, это не работа. Однако,l.emit('end'); полностью работает.

надеюсь, что это поможет. удача.

это сработало для меня ->

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function(){
    setTimeout(function(){
        return gulp.src('sass/*.sass')
        .pipe(sass({indentedSyntax: true}))
        .on('error', console.error.bind(console))
        .pipe(gulp.dest('sass'));
    }, 300);
});



gulp.task('watch', function(){
    gulp.watch('sass/*.sass', ['sass']);
});

gulp.task('default', ['sass', 'watch'])

Я только что добавил .on ('ошибка', консоль.ошибка.привязка (консоль)) линия, но я должен был выполнить глоток команду как root. Я запускаю node gulp на php-приложении, поэтому у меня есть несколько учетных записей на одном сервере, поэтому я столкнулся с проблемой разрыва gulp на синтаксических ошибках, потому что я не запускал gulp как root... Может быть, сантехник и некоторые другие ответы здесь сработали бы для меня, если бы я работал как root. Кредит код Акцио https://www.youtube.com/watch?v=iMR7hq4ABOw для ответа. Он сказал, что, обрабатывая ошибку, она помогает вам определить, на какой строке находится ошибка и что она находится в консоли, но также останавливает gulp от нарушения синтаксической ошибки. Он сказал, что это было своего рода легкий вес исправить, так что не уверен, если он будет работать для того, что вы ищете. Быстро исправить, хотя, стоит попробовать. Надеюсь, это кому-то поможет!

Мне нравится использовать Gulp plumber, потому что он может добавить глобальный слушатель к задаче и отображать значимое сообщение.

var plumber = require('gulp-plumber');

gulp.task('compile-scss', function () {
    gulp.src('scss/main.scss')
        .pipe(plumber())
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(cssnano())
        .pipe(gulp.dest('css/'));
});

Ссылка:https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch

самый простой способ while [ 1 ]; do gulp watch; sleep 0; done.