node.js - home - node lts
Evita que los errores se rompan/se caigan (9)
Con un formato de archivos
(por ejemplo: * .coffee solamente)
Si desea trabajar solo con un formato de archivos, entonces gulp-plumber
es su solución.
Por ejemplo, rich handle errors y 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'' }));
});
Con múltiples tipos de formatos de archivo
(por ejemplo: * .coffee y * .js al mismo tiempo)
Pero si no va a trabajar con varios tipos de formatos de archivo (por ejemplo: *.js
y *.coffee
), entonces publicaré mi solución.
Voy a publicar un código explicativo aquí, con alguna descripción antes.
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.watch(...
el problema con gulp-plumber
y gulp-if
usaba gulp.watch(...
Vea el problema relacionado aquí: https://github.com/floatdrop/gulp-plumber/issues/23
Entonces la mejor opción para mí fue:
- Cada parte como archivo, y concatenar después . Cree múltiples tareas que puedan procesar cada parte en un archivo separado (como lo hace el grunt) y concatenarlas
- Cada parte como secuencia y fusionar las secuencias posteriores . Fusiona dos flujos usando
merge-stream
(que se hizo deevent-stream
) en uno y continúa el trabajo (lo intenté primero, y funciona bien para mí, por lo que es una solución más rápida que la anterior)
Cada parte como secuencia, y fusiona las secuencias después
Ella es la parte principal de mi código:
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'' }));
});
Cada parte como archivo, y concatenar después
Si para separar esto en partes, entonces en cada parte debería haber un archivo de resultados creado. Por ejemplo:
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;
});
PD:
Aquí los módulos de nodo y las funciones que se utilizaron:
// 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'');
};
Estoy ejecutando gulp 3.6.2 y tengo la siguiente tarea que se configuró a partir de una muestra en línea
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'']);
});
Cada vez que hay un error en mi reloj CoffeeScript se detiene, obviamente no es lo que quiero.
Como se recomienda en otra parte, probé esto
gulp.watch([''./app/**/*.coffee''],[''scripts'']).on(''error'', swallowError);
gulp.watch(''./app/**/*.scss'',[''scss'']).on(''error'', swallowError);
function swallowError (error) { error.end(); }
pero parece no funcionar
¿Qué estoy haciendo mal?
En respuesta a la respuesta de @ Aperçu, modifiqué mi método swallowError
e intenté lo siguiente:
gulp.task(''scripts'', function () {
gulp.src(''./app/script/*.coffee'')
.pipe(coffee({ bare: true }))
.pipe(gulp.dest(''./public/js''))
.on(''error'', swallowError);
});
Reinicié, y luego creé un error de sintaxis en mi archivo de café. Mismo problema:
[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)
Esto funcionó para mí ->
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''])
Acabo de agregar la línea .on (''error'', console.error.bind (console)), pero tuve que ejecutar el comando gulp como root. Estoy ejecutando node gulp en una aplicación de php, así que tengo varias cuentas en un servidor, por lo que me encontré con el problema de gulp rompiendo los errores de sintaxis porque no estaba ejecutando gulp como root ... Tal vez fontanero y algunos de los otras respuestas aquí me habrían funcionado si funcioné como root. Crédito al código Accio https://www.youtube.com/watch?v=iMR7hq4ABOw para la respuesta. Dijo que al manejar el error, le ayuda a determinar en qué línea está el error y qué hay en la consola, pero también evita que el trago se rompa en el error de sintaxis. Dijo que era una solución ligera, así que no estoy seguro si funcionará para lo que estás buscando. Solución rápida, vale la pena intentarlo. ¡Espero que esto ayude a alguien!
Implementé el siguiente truco como una solución para 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;
}
Agrégalo a tu gulpfile.js y úsalo así:
gulp.src(src)
// ...
.pipe(uglify({compress: {}}))
.pipe(gulp.dest(''./dist''))
.on(''error'', function (error) {
console.error('''' + error);
});
Esto se siente como el manejo de error más natural para mí. Si no hay controlador de errores, arrojará un error. Probado con el nodo v0.11.13.
Los ejemplos anteriores no funcionaron para mí. Lo siguiente hizo sin embargo:
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'']);
});
Me gusta usar el fontanero gulp porque puede agregar un oyente global a una tarea y mostrar un mensaje significativo.
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/''));
});
Referencia: https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch
Su función swallowError
debería verse así:
function swallowError (error) {
// If you want details of the error in the console
console.log(error.toString())
this.emit(''end'')
}
Creo que debe vincular esta función al evento de error
de la tarea que estaba cayendo, no a la tarea de watch
, porque no es allí donde surge el problema, debe establecer esta devolución de llamada de error en cada tarea que puede fallar, como complementos que se rompen cuando te has perdido una ;
o algo más, para evitar que la tarea de watch
detenga.
Ejemplos:
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''))
})
Alternativamente, si no le importa incluir otro módulo, puede usar la función de registro de gulp-util para evitar que declare una función adicional en su gulpfile
:
.on(''error'', gutil.log)
Pero puedo recomendar echarle un vistazo al impresionante plugin gulp-plumber , que se usa para eliminar el controlador onerror
del evento de error
, causando la ruptura de las secuencias. Es muy simple de usar y evita que detectes todas las tareas que pueden fallar.
gulp.src(''./app/script/*.coffee'')
.pipe(plumber())
.pipe(coffee({ bare: true }))
.pipe(gulp.dest(''./public/js''))
Más información sobre esto en este artículo por el creador del plugin en cuestión.
Una solución simple a esto es poner el gulp watch
en un bucle infinito dentro de un shell Bash (o sh).
while true; do gulp; gulp watch; sleep 1; done
Mantenga la salida de este comando en un área visible en su pantalla mientras edita su JavaScript. Cuando las ediciones resulten en un error, Gulp se bloqueará, imprimirá su seguimiento de pila, esperará un segundo y reanudará la visualización de sus archivos de origen. A continuación, puede corregir el error de sintaxis, y Gulp indicará si la edición fue exitosa, ya sea imprimiendo su salida normal o bloqueando (luego reanudando) nuevamente.
Esto funcionará en una terminal Linux o Mac. Si está usando Windows, use Cygwin o Ubuntu Bash (Windows 10).
la manera más fácil while [ 1 ]; do gulp watch; sleep 0; done
while [ 1 ]; do gulp watch; sleep 0; done
while [ 1 ]; do gulp watch; sleep 0; done
.
Mecanografiado
Esto es lo que funcionó para mí. Trabajo con Typescript
y separó la función (para una mayor confusión con this
palabra clave) para manejar less
. Esto funciona con Javascript
también.
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''))
})
Ahora, cuando watch
archivos .less
y error
produzca un error
, el watch
no se detendrá y los nuevos cambios se procesarán según su less task
.
NOTA : Intenté con l.end();
; Sin embargo, no funcionó. Sin embargo, l.emit(''end'');
totalmente funciona
Espero que esto ayude. Buena suerte.