Ich verwende gulp 3.6.2 und habe die folgende Aufgabe, die aus einem Online-Beispiel eingerichtet wurde
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']);
});
Jedes Mal, wenn ein Fehler in meiner CoffeeScript-Schluckuhr auftritt, ist offensichtlich nicht das, was ich will.
Wie an anderer Stelle empfohlen, habe ich dies versucht
gulp.watch(['./app/**/*.coffee'],['scripts']).on('error', swallowError);
gulp.watch('./app/**/*.scss',['scss']).on('error', swallowError);
function swallowError (error) { error.end(); }
aber es scheint nicht zu funktionieren.
Was mache ich falsch?
Als Antwort auf die Antwort von @ Aperçu habe ich meine swallowError
-Methode geändert und stattdessen Folgendes versucht:
gulp.task('scripts', function () {
gulp.src('./app/script/*.coffee')
.pipe(coffee({ bare: true }))
.pipe(gulp.dest('./public/js'))
.on('error', swallowError);
});
Neustart und erstellte dann einen Syntaxfehler in meiner Kaffeedatei. Gleicher Fehler:
[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)
Ihre swallowError
-Funktion sollte so aussehen:
function swallowError (error) {
// If you want details of the error in the console
console.log(error.toString())
this.emit('end')
}
Ich denke, Sie müssen diese Funktion an das error
-Ereignis der fallenden Task binden, nicht an die watch
-Task, da das Problem hier nicht auftritt. Sie sollten diesen Fehler-Callback für jede Task festlegen, die möglicherweise fehlschlägt, wie Plugins, die abbrechen Sie haben einen ;
oder etwas anderes verpasst, um zu verhindern, dass watch
beendet wird.
Beispiele:
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'))
})
Wenn Sie nichts dagegen haben, ein anderes Modul hinzuzufügen, können Sie die log - Funktion von gulp-util verwenden, um zu verhindern, dass Sie in Ihrer gulpfile
eine zusätzliche Funktion deklarieren:
.on('error', gutil.log)
Ich kann jedoch einen Blick auf das fantastische - gulp-plumber - Plugin werfen, das zum Entfernen des onerror
-Handlers des error
-Ereignisses verwendet wird, wodurch die Streams unterbrochen werden. Es ist sehr einfach zu bedienen und hält Sie davon ab, alle Aufgaben zu erfassen, die möglicherweise fehlschlagen.
gulp.src('./app/script/*.coffee')
.pipe(plumber())
.pipe(coffee({ bare: true }))
.pipe(gulp.dest('./public/js'))
Mehr Infos dazu auf diesem Artikel vom Ersteller des betreffenden Plugins.
Die obigen Beispiele haben für mich nicht funktioniert. Folgendes tat es jedoch:
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']);
});
(zB: * .coffee)
Wenn Sie nur mit einem Dateiformat arbeiten möchten, ist gulp-plumber
Ihre Lösung.
Zum Beispiel reich behandelte Fehler und Warnungen beim Kaffeescripting:
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' }));
});
(zB: * .coffee und * .js gleichzeitig)
Wenn Sie jedoch nicht mit mehreren Arten von Dateiformaten arbeiten (z. B. *.js
und *.coffee
), werde ich meine Lösung veröffentlichen.
Ich werde hier einfach einen selbsterklärenden Code posten, mit einer Beschreibung vorher.
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' }));
});
Ich habe das Problem mit gulp-plumber
und gulp-if
mit gulp.watch(...
konfrontiert.
Siehe verwandtes Problem hier: https://github.com/floatdrop/gulp-plumber/issues/23
Die beste Option für mich war also:
merge-stream
(die aus event-stream
erstellt wurden) zu einem und setzen Sie den Job fort (ich habe es zuerst probiert, und es funktioniert gut für mich, sodass es eine schnellere Lösung ist als der vorherige).Ihr ist der Hauptteil meines Codes:
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' }));
});
Wenn dies in Teile unterteilt werden soll, sollte in jedem Teil eine Ergebnisdatei erstellt werden. ZB:
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;
});
Hier Knotenmodule und Funktionen, die verwendet wurden:
// 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');
};
Ich benutze gerne Klempner, weil er einer Aufgabe einen globalen Listener hinzufügen und eine aussagekräftige Meldung anzeigen kann.
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/'));
});
Referenz: https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch
Eine einfache Lösung dafür ist, gulp watch
in eine Endlosschleife innerhalb einer Bash- (oder Sh-) Shell zu setzen.
while true; do gulp; gulp watch; sleep 1; done
Behalten Sie die Ausgabe dieses Befehls in einem sichtbaren Bereich auf Ihrem Bildschirm, wenn Sie Ihr JavaScript bearbeiten. Wenn Ihre Bearbeitungen zu einem Fehler führen, stürzt Gulp ab, druckt die Stapelablaufverfolgung, wartet eine Sekunde und nimmt die Überwachung der Quelldateien wieder auf. Sie können dann den Syntaxfehler korrigieren, und Gulp zeigt an, ob die Bearbeitung erfolgreich war oder nicht, indem Sie entweder die normale Ausgabe ausdrucken oder abstürzen (und dann wieder fortsetzen).
Dies funktioniert in einem Linux- oder Mac-Terminal. Wenn Sie Windows verwenden, verwenden Sie Cygwin oder Ubuntu Bash (Windows 10).
Ich habe den folgenden Hack als Workaround für https://github.com/gulpjs/gulp/issues/71 implementiert:
// 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;
}
Fügen Sie es Ihrer Datei gulpfile.js hinzu und verwenden Sie es so:
gulp.src(src)
// ...
.pipe(uglify({compress: {}}))
.pipe(gulp.dest('./dist'))
.on('error', function (error) {
console.error('' + error);
});
Das fühlt sich für mich die natürlichste Fehlerbehandlung an. Wenn überhaupt kein Fehlerhandler vorhanden ist, wird ein Fehler ausgegeben. Getestet mit Node v0.11.13.
TypeScript
Das hat bei mir funktioniert. Ich arbeite mit TypeScript
und trenne die Funktion (um Verwechslungen mit dem this
-Schlüsselwort zu vermeiden), um mit less
zu arbeiten. Dies funktioniert auch mit 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'))
})
Wenn Sie nun watch
.less
-Dateien verwenden und eine error
auftritt, wird die watch
nicht angehalten und neue Änderungen werden entsprechend Ihrem less task
verarbeitet.
NOTE: Ich habe es mit l.end();
versucht; es hat jedoch nicht funktioniert. l.emit('end');
funktioniert jedoch völlig.
Ich hoffe das hilft. Viel Glück.
Das hat für mich funktioniert ->
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'])
Ich habe gerade das .__ hinzugefügt. .on ('error', console.error.bind (console)) Zeile, aber ich musste die .__ ausführen. gulp Befehl als root. Ich verwende node gulp auf einer PHP-Anwendung, so dass ich mehrere Konten auf einem Server habe. Aus diesem Grund bin ich auf das Problem des Schluckens von Syntaxfehlern gestoßen, weil ich nicht als root ausgeführt habe ... Vielleicht Klempner und einige der Andere Antworten hier hätten für mich funktioniert, wenn ich als root ausgeführt würde . Credit to Accio Code https://www.youtube.com/watch?v=iMR7hq4ABOw für die Antwort. Er sagte, durch die Fehlerbehandlung hilft es Ihnen zu bestimmen, in welcher Zeile sich der Fehler befindet und was in der Konsole ist, aber er verhindert auch, dass Schluck bei Syntaxfehlern bricht. Er sagte, es sei eine Art leichtes Problem, also nicht sicher, ob es für das funktioniert, wonach Sie suchen. Schnelle Lösung, einen Versuch wert. Hoffe das hilft jemandem!