J'utilise gulp 3.6.2 et la tâche suivante a été configurée à partir d'un exemple en ligne.
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']);
});
Chaque fois qu'il y a une erreur dans ma montre CoffeeScript Gulp, la montre s'arrête - évidemment pas ce que je veux.
Comme recommandé ailleurs j'ai essayé ceci
gulp.watch(['./app/**/*.coffee'],['scripts']).on('error', swallowError);
gulp.watch('./app/**/*.scss',['scss']).on('error', swallowError);
function swallowError (error) { error.end(); }
mais cela ne semble pas fonctionner.
Qu'est-ce que je fais mal?
En réponse à la réponse de @ Aperçu, j'ai modifié ma méthode swallowError
et essayé à la place:
gulp.task('scripts', function () {
gulp.src('./app/script/*.coffee')
.pipe(coffee({ bare: true }))
.pipe(gulp.dest('./public/js'))
.on('error', swallowError);
});
Redémarré, puis créé une erreur de syntaxe dans mon fichier café. Même problème:
[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)
Votre fonction swallowError
devrait ressembler à ceci:
function swallowError (error) {
// If you want details of the error in the console
console.log(error.toString())
this.emit('end')
}
Je pense que vous devez lier cette fonction à l’événement error
de la tâche en train de tomber, et non à la tâche watch
, car ce n’est pas la source du problème, vous devez définir ce rappel d’erreur sur chaque tâche susceptible d’échouer, comme les plugins qui se cassent lorsque vous avez manqué un ;
ou autre chose pour empêcher la tâche watch
de s'arrêter.
Exemples :
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'))
})
Sinon, si cela ne vous dérange pas d'inclure un autre module, vous pouvez utiliser la fonction log de gulp-util pour vous empêcher de déclarer une fonction supplémentaire dans votre gulpfile
:
.on('error', gutil.log)
Mais je recommanderais peut-être de jeter un coup d'oeil au plugin génial gulp-plumber, qui est utilisé pour supprimer le gestionnaire onerror
de l'événement error
, ce qui provoque la rupture des flux. Son utilisation est très simple et vous évite d’attraper toutes les tâches qui risquent d’échouer.
gulp.src('./app/script/*.coffee')
.pipe(plumber())
.pipe(coffee({ bare: true }))
.pipe(gulp.dest('./public/js'))
Plus d'informations à ce sujet sur cet article par le créateur du plugin concerné.
Les exemples ci-dessus n'ont pas fonctionné pour moi. Ce qui suit a cependant:
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']);
});
(ex: * .café seulement)
Si vous voulez travailler avec un seul format de fichier, alors gulp-plumber
est votre solution.
Par exemple, Rich gère les erreurs et les avertissements relatifs à 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' }));
});
(ex: * .coffee et * .js en même temps)
Mais si vous ne voulez pas travailler avec plusieurs types de formats de fichiers (par exemple: *.js
et *.coffee
), alors je posterai ma solution.
Je vais simplement poster un code explicatif ici, avec une description avant.
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' }));
});
J'ai fait face au problème avec gulp-plumber
et gulp-if
en utilisant gulp.watch(...
Voir la question associée ici: https://github.com/floatdrop/gulp-plumber/issues/23
La meilleure option pour moi était donc:
merge-stream
(qui a été créé à partir de event-stream
) en un et continuer le travail (j’ai essayé d’abord, et cela fonctionne bien pour moi, donc c’est une solution plus rapide que le précédent)Elle est la partie principale de mon 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' }));
});
Si séparer ceci en parties, alors dans chaque partie, un fichier de résultat devrait être créé. Pour 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;
});
Voici les modules de nœuds et les fonctions utilisés:
// 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');
};
J'aime utiliser gulp plombier, car il permet d'ajouter un écouteur global à une tâche et d'afficher un message significatif.
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/'));
});
Référence: https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch
Une solution simple consiste à placer gulp watch
dans une boucle infinie dans un shell Bash (ou sh).
while true; do gulp; gulp watch; sleep 1; done
Conservez le résultat de cette commande dans une zone visible de votre écran lorsque vous modifiez votre code JavaScript. Lorsque vos modifications entraînent une erreur, Gulp se bloque, affiche sa trace de pile, attend une seconde et continue à regarder vos fichiers source. Vous pouvez ensuite corriger l'erreur de syntaxe et Gulp indiquera si la modification a réussi ou non en imprimant sa sortie normale ou en bloquant à nouveau (puis en reprenant).
Cela fonctionnera dans un terminal Linux ou Mac. Si vous utilisez Windows, utilisez Cygwin ou Ubuntu Bash (Windows 10).
J'ai mis en œuvre le piratage suivant comme solution de contournement pour 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;
}
Ajoutez-le à votre fichier gulpfile.js et utilisez-le comme ça:
gulp.src(src)
// ...
.pipe(uglify({compress: {}}))
.pipe(gulp.dest('./dist'))
.on('error', function (error) {
console.error('' + error);
});
Cela ressemble à la gestion d'erreur la plus naturelle pour moi. S'il n'y a pas du tout de gestionnaire d'erreur, une erreur sera générée. Testé avec le noeud v0.11.13.
TypeScript
C'est ce qui a fonctionné pour moi. Je travaille avec TypeScript
et ai séparé la fonction (pour éviter toute confusion avec le mot clé this
) afin de gérer less
. Cela fonctionne aussi avec 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'))
})
Désormais, lorsque vous watch
.less
fichiers et qu'une error
se produit, la watch
ne s’arrête pas et les nouvelles modifications sont traitées conformément à votre less task
.
NOTE: J'ai essayé avec l.end();
; Cependant, cela n'a pas fonctionné. Cependant, l.emit('end');
fonctionne totalement.
J'espère que cette aide. Bonne chance.
Cela a fonctionné pour moi ->
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'])
Je viens d'ajouter le .on ('error', console.error.bind (console)) , mais je devais exécuter le gulp commande en tant que racine. J'exécute node gulp sur une application php, de sorte que j'ai plusieurs comptes sur un serveur. C'est pourquoi j'ai rencontré le problème de gulp rupture sur les erreurs de syntaxe car je n'exécutais pas gulp en tant que root ... Peut-être que le plombier et certains des d’autres réponses ici auraient fonctionné pour moi si j’exécutais le compte root . Crédit de Accio Code https://www.youtube.com/watch?v=iMR7hq4ABOw pour la réponse. Il a dit qu'en gérant l'erreur, il vous aide à déterminer la ligne sur laquelle l'erreur est affichée et ce qu'elle est dans la console, mais empêche également gulp de rompre en cas d'erreur de syntaxe. Il a dit que c'était une sorte de solution légère, alors vous ne savez pas si cela fonctionnera pour ce que vous recherchez. Solution rapide cependant, vaut le coup. J'espère que cela aide quelqu'un!