Hataların gulp saatini kırmasını / çökmesini önleme


178

Gulp 3.6.2 kullanıyorum ve çevrimiçi olarak bir örnekten kurulmuş aşağıdaki göreve sahibim

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 saatimde herhangi bir hata olduğunda - istediğim gibi değil.

Başka bir yerde önerildiği gibi bunu denedim

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

ama işe yaramıyor gibi görünüyor.

Neyi yanlış yapıyorum?


@ Aperçu'nun cevabına yanıt olarak yöntemimi değiştirdim swallowErrorve bunun yerine aşağıdakileri denedim:

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

Yeniden başlatıldı ve daha sonra kahve dosyamda bir sözdizimi hatası oluşturdu. Aynı sorun:

[gulp] Finished 'scripts' after 306 μs

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: W:\bariokart\app\script\trishell.coffee:5:1: error: unexpected *
*
^
  at Stream.modifyFile (W:\bariokart\node_modules\gulp-coffee\index.js:37:33)
  at Stream.stream.write (W:\bariokart\node_modules\gulp-coffee\node_modules\event-stream\node_modules\through\index.js:26:11)
  at Stream.ondata (stream.js:51:26)
  at Stream.EventEmitter.emit (events.js:95:17)
  at queueData (W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:43:21)
  at next (W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:71:7)
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:85:7
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\lib\src\bufferFile.js:8:5
  at fs.js:266:14
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\graceful-fs\graceful-fs.js:104:5
  at Object.oncomplete (fs.js:107:15)

3
github.com/gulpjs/gulp/tree/master/docs/recipes adresindeki resmi yudum tariflerine bakın ... akış-birleştirici2 kullanarak akışları-işlemek-hataları-ele almak için bu resmi cevap!
danday74

Yanıtlar:


257

Sizin swallowErrorfonksiyonu şu şekilde görünmelidir:

function swallowError (error) {

  // If you want details of the error in the console
  console.log(error.toString())

  this.emit('end')
}

Bence bu işlevi errorgörev değil, düşen görev durumunda bağlamak zorunda watch, çünkü sorun burada geliyor değil, bu hata geri arama başarısız olabilir her görevde, ne zaman kırılır eklentiler gibi ayarlamanız gerekir görevi durdurmak ;için bir ya da başka bir şey kaçırdı watch.

Örnekler:

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

  gulp.src('css/*.scss')
    .pipe(sass({ compass: true }))
    .on('error', swallowError)
    .pipe(cssmin())
    .pipe(gulp.dest('dist'))
})

Başka bir modül eklemek sakıncası yoksa Alternatif olarak, kullanabileceğiniz günlük işlevini yudum-util Gözlerinde farklı bir açıklamadan ekstra fonksiyon tutmak için gulpfile:

.on('error', gutil.log)

Ancak , olayın işleyicisini kaldırmak için kullanılan ve akarsuların bozulmasına neden olan harika gulp-tesisatçı eklentisine bakmanızı tavsiye edebilirim . Kullanımı çok basit ve başarısız olabilecek tüm görevleri yakalamanızı engelliyor.onerrorerror

gulp.src('./app/script/*.coffee')
  .pipe(plumber())
  .pipe(coffee({ bare: true }))
  .pipe(gulp.dest('./public/js'))

İlgili eklentinin yaratıcısı tarafından bu makale hakkında daha fazla bilgi .


Yardımın için minnettarım. Düzenlememe bakın. Sanırım söylediğini yapıyorum ve hala çalışmıyor
George Mauer

2
Cevabınızı, yapılacak son doğru şeyi yansıtacak şekilde düzenlemek isteyebilirsiniz, böylece gelecekte bunu bulan herkes yorum zincirini okumak zorunda kalmaz.
George Mauer

1
Her şey yolunda ve güzel, ama neden kendi hata işleyicileri yazmak zorundayım? Yutmak veya homurdanmak ya da herhangi bir önişleme aracı kullanmamın tek nedeni, kirli işi benim için yapmasıdır. Kodumda bir yerde bir sözdizimi hatası (gerçekleşmesi zorunludur) tüm sistemi durduramaz. Bunu Prepros'un GUI'siyle (başka bir önişlemci) karşılaştırın - bu araç size hatanızın tam olarak nerede olduğunu söyler ve bir şey yanlış olduğunda takılmaz veya çıkmaz.
Kokodoko

1
resmi yudum tarifi olmasına rağmen hiç kimsenin steam-combiner2'den bahsetmediği şaşırtıcı! tesisatçı da iyi ama her zaman gulp tarifleri takip etmeyi tercih ediyorum, gulp tarifleri gulp
danday74

1
Aynı muamma ile karşı karşıya kaldığımda , özellikle asmak için esnek hale getirmek istediğim saat görevi olduğu için, saat işlevinin sonucuna gulp.watch()bir ekleyen bir sarıcı kullanmaya karar verdim .on('error', function() { this.emit('end') }). Gerçekten iyi çalışıyor ve başarısız olan bireysel görevler hala kendi hata mesajlarını yazdırıyor. Kodu inceleyin: github.com/specious/specious.github.io/commit/f8571d28
tknomad

20

Yukarıdaki örnekler benim için işe yaramadı. Ancak şunu yaptı:

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

Bu harika, ama aynı zamanda bir hata varsa (şu anda bu sadece terminalde hata kaydeder) bildirmek iyi olurdu
raison

4

Bir dosya biçimi ile

(ör .: *. sadece kahve)

Yalnızca tek bir dosya biçimiyle çalışmak istiyorsanız gulp-plumberçözümünüz budur.

Örneğin, zengin işlenmiş hatalar ve kahve tanımlama için uyarı:

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

Birden çok dosya formatı ile

(örneğin: * .kahve ve * .js aynı anda)

Ancak, birden fazla dosya formatı türüyle (örneğin: *.jsve *.coffee) çalışmazsanız, çözümümü göndereceğim.

Daha önce bazı açıklamalarla birlikte buraya açıklayıcı bir kod göndereceğim.

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

Sorunla karşılaştım gulp-plumberve gulp-ifkullandımgulp.watch(...

İlgili konuya buradan bakın: https://github.com/floatdrop/gulp-plumber/issues/23

Benim için en iyi seçenek:

  • Her bölümü dosya olarak birleştirin ve sonra birleştirin . Her bir parçayı ayrı bir dosyada işleyebilen birden fazla görev oluşturun (homurdanıyor gibi) ve bunları birleştirin
  • Her bölüm akış olarak ve sonra akışları birleştirmek . Birinden merge-stream(yapılan event-stream) kullanarak iki akışı birleştirin ve işe devam edin (önce denedim ve benim için iyi çalışıyor, bu yüzden öncekinden daha hızlı bir çözüm)

Her bölüm akış olarak ve sonra akışları birleştir

O benim kodun ana parçasıdır:

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

Her bölüm dosya olarak ve sonra bitiştir

Bunu parçalara ayırmak için, her parçada bir sonuç dosyası oluşturulmalıdır. Örneğin:

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;

});

Not:

Burada kullanılan düğüm modülleri ve işlevleri:

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

Bu yorumlar için hala iyileştirmeler görüyorum. Hız karşılaştırması gibi ve yalnızca .js dosyaları için bağlantı (küçültülmüş veya 3B parti kitaplıkları veya bower_component'lardan gelen kütüphaneler hariç). Ama temelde bu koklamayı Google.com tarafından ayarlamak ve çözmek kolaydır
Roman M.Koss


2

Https://github.com/gulpjs/gulp/issues/71 için geçici bir çözüm olarak aşağıdaki hack'i uyguladım :

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

Gulpfile.js dosyasına ekleyin ve şöyle kullanın:

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

Bu benim için en doğal hata işleme gibi geliyor. Hiçbir hata giderici yoksa, hata verir. Düğüm v0.11.13 ile test edilmiştir.


2

Bunun basit bir çözümü, gulp watchbir Bash (veya sh) kabuğu içine sonsuz bir döngü koymaktır .

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

JavaScript'inizi düzenlerken bu komutun çıktısını ekranınızda görünür bir alanda tutun. Düzenlemeleriniz bir hataya neden olduğunda, Gulp çökecek, yığın izlemesini yazdıracak, bir saniye bekleyecek ve kaynak dosyalarınızı izlemeye devam edecektir. Daha sonra sözdizimi hatasını düzeltebilirsiniz ve Gulp, normal çıktısını yazdırarak veya yeniden kilitleyerek (sonra yeniden başlatarak) düzenlemenin başarılı olup olmadığını gösterecektir.

Bu bir Linux veya Mac terminalinde çalışacaktır. Windows kullanıyorsanız Cygwin veya Ubuntu Bash kullanın (Windows 10).


Bu hangi dil? Ayrıca, önerilen çözümlere göre bunun herhangi bir faydası var mı?
George Mauer

Bash / sh ile yazılmıştır. Diğer çözümlerden daha az kod gerektirir ve hatırlanması ve uygulanması daha kolaydır.
Jesse Hogan

Bunun bash'ı ve bu konudaki diğer düşüncelerinizi cevabınıza düzenleyebilir misiniz? Daha sonra tesisatçı, ama geçerli (çapraz platform değilse) bir yaklaşım olduğunu kabul etmiyorum. Başlangıçta oy kullandım, çünkü hangi dilde olduğu bile belli değildi ve yanıtı düzenlemediğiniz sürece oyumu değiştiremem.
George Mauer

1
Yani akışı çökmeyi ve sadece hatayı yakalamak yerine sonsuz bir döngü ile ne yaptığınıza bağlı olarak biraz zaman alabilecek tüm süreci yeniden başlatmayı mı tercih edersiniz? Beni biraz rahatsız ediyor gibi görünüyor. Daha az koddan bahsetmek için, görevinize tesisatçı eklemeniz için 16 karakter gerektirirken, çözümünüz sayılmadan 36 alır gulp watch.
Balthazar

Geri bildiriminiz için teşekkürler, @GeorgeMauer, düzenlemeleri yaptım ve içinde çalıştığı ortamlar / platformlar hakkında yazdım.
Jesse Hogan

1

daktilo ile yazılmış yazı

Bu benim için işe yaradı. Ben ile çalışmak Typescriptve thisişlemek için ( anahtar kelime ile karışıklık önlemek için) işlevi ayrılmış less. Bu da işe yarıyor 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'))
})

Şimdi, watch .lessdosya ve bir errorgerçekleştiğinde, watchdurmaz ve yeni değişiklikler sizin göre işlenir less task.

NOT : Ben denedim l.end();; ancak, işe yaramadı. Ancak, l.emit('end');tamamen işe yarıyor.

Umarım bu yardım. İyi şanslar.


1

Bu benim için çalıştı ->

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'])

Az önce .on ('error', console.error.bind (console)) satırını ekledim, ancak gulp komutunu root olarak çalıştırmak zorunda kaldım. Ben bir sunucuda birden fazla hesabı var, bu yüzden ben bir kök üzerinde birden fazla hesap var düğüm gulp çalıştırıyorum, bu yüzden ben root olarak gulp çalışmıyordu çünkü ben sözdizimi hataları kırma meselesine koştu ... Belki tesisatçı ve bazı Eğer kök olarak koşsaydım, buradaki diğer cevaplar benim için işe yarardı. Accio Koduna https://www.youtube.com/watch?v=iMR7hq4ABYanıt için teşekkür ederiz. Hatayı ele alarak hatanın hangi satırda ve konsolda ne olduğunu belirlemenize yardımcı olduğunu, ancak aynı zamanda yeminin sözdizimi hatasına girmesini durdurduğunu söyledi. Bunun hafif bir düzeltme olduğunu söyledi, bu yüzden aradığınız şey için çalışıp çalışmayacağından emin değilim. Hızlı düzeltme olsa da, denemeye değer. Umarım bu birine yardımcı olur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.