防止错误打破/碰撞吞噬手表
我正在运行gulp 3.6.2,并从网上的一个示例中build立了以下任务
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吞吐手表出现错误的时候,显然不是我想要的。
正如其他地方所build议的,我试过
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); });
重新启动,然后在我的咖啡文件中创build一个语法错误。 同样的问题:
[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)
你的swallowError
函数应该是这样的:
function swallowError (error) { // If you want details of the error in the console console.log(error.toString()) this.emit('end') }
我认为你必须绑定这个函数的任务,而不是watch
任务的error
事件,因为这不是问题出在哪里,你应该在每个可能失败的任务上设置这个错误callback,比如当插件崩溃的时候你错过了一个;
或别的什么东西,以防止watch
任务停止。
例子 :
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')) })
或者,如果您不介意包含其他模块,则可以使用gulpfile
-util的日志function来防止在您的gulpfile
声明一个额外的函数:
.on('error', gutil.log)
但是我可能会推荐看一下真棒吞咽插件插件,它用于删除error
事件的onerror
处理程序,导致stream的中断。 它使用起来非常简单,它阻止了你捕捉所有可能失败的任务。
gulp.src('./app/script/*.coffee') .pipe(plumber()) .pipe(coffee({ bare: true })) .pipe(gulp.dest('./public/js'))
有关此插件的创build者在本文中的更多信息。
上面的例子不适合我。 但是下面做了:
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']); });
用一种格式的文件
(例如:* .coffee)
如果你只想用一种格式的文件工作,那么gulp-plumber
就是你的解决scheme。
例如,富处理错误和咖啡脚本警告:
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' })); });
使用多种types的文件格式
(例如:* .coffee和* .js同时)
但是,如果您不想使用多种types的文件格式(例如: *.js
和*.coffee
),那么我将发布我的解决scheme。
我只会在这里发表一个自我解释的代码,之前有一些描述。
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(...
gulp-plumber
和gulp.watch(...
来gulp.watch(...
这个问题gulp-if
使用gulp.watch(...
在这里看到相关的问题: https : //github.com/floatdrop/gulp-plumber/issues/23
所以对我来说最好的select是:
- 每个部分作为文件,并连接在一起 。 创build多个任务,可以在单独的文件中处理每个部分(如grunt),并连接它们
- 每个部分作为stream,并合并后的stream 。 合并两个stream使用
merge-stream
(这是从event-stream
)成一个,并继续工作(我先试了,它对我来说工作得很好,所以它比以前更快的解决scheme)
每个部分作为stream,并合并后的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' })); });
每个部分作为文件,并连接在一起
如果要把它分成几部分,那么在每个部分都应该有一个结果文件被创build。 例如:
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; });
PS:
这里使用的节点模块和function:
// 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的一种解决方法,我已经实施了以下hack:;
// 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并使用它:
gulp.src(src) // ... .pipe(uglify({compress: {}})) .pipe(gulp.dest('./dist')) .on('error', function (error) { console.error('' + error); });
这感觉就像是对我来说最自然的error handling。 如果没有error handling程序,它将会抛出一个错误。 testing节点v0.11.13。
打字稿
这是为我工作。 我使用Typescript
和分隔function(以避免与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');
完全有效。
希望这个帮助。 祝你好运。
一个简单的解决scheme就是在一个Bash(或者sh)shell中将gulp watch
放在一个无限循环中。
while true; do gulp; gulp watch; sleep 1; done
在编辑JavaScript时,将此命令的输出保持在屏幕上的可见区域。 当您的编辑导致错误时,Gulp将崩溃,打印堆栈跟踪,等待一秒钟,然后继续观看源文件。 然后,您可以更正语法错误,Gulp会通过打印出正常的输出或者再次崩溃(然后恢复)来指示编辑是否成功。
这将在Linux或Macterminal工作。 如果您使用Windows,请使用Cygwin或Ubuntu Bash(Windows 10)。
这对我有用 – >
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('error',console.error.bind(console))行,但是我必须以root身份运行gulp命令。 我在一个PHP应用程序运行节点吞咽,所以我有一个服务器上的多个帐户,这就是为什么我遇到了吞咽打破语法错误的问题,因为我没有作为根运行gulp …也许水pipe工和一些如果我以root身份运行,这里的其他答案会对我有用。 感谢Accio Code https://www.youtube.com/watch?v=iMR7hq4ABOw获取答案。; 他说,通过处理这个错误,它可以帮助你确定错误是在哪里,在控制台中是什么,也可以避免吞咽语法错误。 他说这是一个轻量级的解决scheme,所以不知道它是否适用于你正在寻找的东西。 快速修复,但值得一试。 希望这可以帮助别人!
最简单的方法while [ 1 ]; do gulp watch; sleep 0; done
while [ 1 ]; do gulp watch; sleep 0; done
while [ 1 ]; do gulp watch; sleep 0; done
。