Programming

Gulp 시계가 깨지거나 충돌하는 것을 방지

procodes 2020. 5. 23. 23:05
반응형

Gulp 시계가 깨지거나 충돌하는 것을 방지


gulp 3.6.2를 실행 중이며 샘플 온라인에서 설정 한 다음 작업이 있습니다.

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 시계에 오류가 발생하면 언제든지 내가 원하는 것이 아닙니다.

다른 곳에서 추천했듯이 이것을 시도했습니다.

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

다시 시작한 다음 커피 파일에 구문 오류가 발생했습니다. 같은 문제 :

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

error작업이 아닌 떨어지는 작업의 경우이 기능을 바인딩해야한다고 생각합니다 watch. 문제가있는 곳이 아니기 때문에 실패 할 수있는 플러그인과 같이 실패 할 수있는 각 작업 에서이 오류 콜백을 설정해야합니다. 작업이 중지 ;되는 것을 방지하기 위해 또는 다른 것을 놓쳤습니다 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'))
})

또는 다른 모듈을 포함하지 않으려는 경우 gulp-utillog 함수를 사용하여 추가 함수를 선언하지 못하게 할 수 있습니다 .gulpfile

.on('error', gutil.log)

그러나 이벤트 처리기 를 제거 하여 스트림이 중단 되는 멋진 gulp-plumber 플러그인을 살펴 보는 것이 좋습니다 . 사용하기 매우 간단하며 실패 할 수있는 모든 작업을 잡을 수 없습니다.onerrorerror

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

관련 플러그인의 작성자 가이 기사대한 자세한 정보를 제공합니다 .


위의 예제는 저에게 효과적이지 않았습니다. 그러나 다음은 수행했습니다.

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

한 가지 형식의 파일

(예 : *. 커피 만)

한 가지 형식의 파일로만 작업하려면 gulp-plumber솔루션이 필요합니다.

예를 들어 풍부한 처리 오류 및 커피 스크립팅에 대한 경고 :

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

여러 유형의 파일 형식

(예 : * .coffee와 * .js를 동시에)

그러나 여러 유형의 파일 형식 (예 : *.js*.coffee) 으로 작업하지 않으면 솔루션을 게시합니다.

여기에 설명이 포함 된 자체 설명 코드를 게시하겠습니다.

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-plumber하고 있는 문제에 직면했다.gulp-ifgulp.watch(...

https://github.com/floatdrop/gulp-plumber/issues/23에서 관련 문제를 참조하십시오.

그래서 가장 좋은 옵션은 다음과 같습니다.

  • 각 부분은 파일로 사용되며 이후에 연결 됩니다. grunt처럼 별도의 파일로 각 부분을 처리 할 수있는 여러 작업을 생성하고 연결
  • 각 부분은 스트림으로, 스트림을에 병합합니다 . merge-stream(에서 만든 event-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' }));
});

각 부분은 파일로 연결되고

이것을 부분으로 분리하면 각 부분에 결과 파일이 작성되어야합니다. 예를 들어 :

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;

});

추신:

사용 된 노드 모듈 및 기능은 다음과 같습니다.

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

나는 gulp 배관공을 사용하여 작업에 전역 리스너를 추가하고 의미있는 메시지를 표시 할 수 있기 때문에 사용하고 싶습니다.

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

참조 : https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch


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

gulpfile.js에 추가하고 다음과 같이 사용하십시오.

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

이것은 나에게 가장 자연스러운 오류 처리처럼 느껴집니다. 오류 처리기가 전혀 없으면 오류가 발생합니다. 노드 v0.11.13으로 테스트되었습니다.


A simple solution to this is to put gulp watch in an infinite loop within a Bash (or sh) shell.

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

Keep the output of this command in a visible area on your screen as you edit your JavaScript. When your edits result in an error, Gulp will crash, print its stack trace, wait for a second, and resume watching your source files. You can then correct the syntax error, and Gulp will indicate whether or not the edit was a success by either printing out it's normal output, or crashing (then resuming) again.

This will work in a Linux or Mac terminal. If you are using Windows, use Cygwin or Ubuntu Bash (Windows 10).


Typescript

This is what worked for me. I work with Typescript and separated the function (to aovid confusion with this keyword) to handle less. This works with Javascript as well.

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

Now, when you watch .less files, and an error occurs, the watch will not stop and new changes will processed as per your less task.

NOTE : I tried with l.end();; however, it did not work. However, l.emit('end'); totally works.

Hope this help. Good Luck.


This worked for me ->

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

I just added the .on('error', console.error.bind(console)) line, but I had to run the gulp command as root. I'm running node gulp on a php application so I have multiple accounts on one server, which is why I ran into the issue of gulp breaking on syntax errors because I was not running gulp as root... Maybe plumber and some of the other answers here would have worked for me if I ran as root. Credit to Accio Code https://www.youtube.com/watch?v=iMR7hq4ABOw for the answer. He said that by handling the error it helps you to determine what line the error is on and what it is in the console, but also stops gulp from breaking on syntax error. He said it was kind of a light weight fix, so not sure if it will work for what you are looking for. Quick fix though, worth a shot. Hope this helps someone!

참고URL : https://stackoverflow.com/questions/23971388/prevent-errors-from-breaking-crashing-gulp-watch

반응형