2016-06-03 2 views
9

Я разрабатываю машинопись проект со следующим построением этапов:Глоток часы прекращает или строит всю задачу цепочке

  • линта
  • сборка
  • тест

Я использую Gulp 4.0 как инструмент сборки, и хотите иметь задачу просмотра, которая должна инициировать тест (что означает, что ранее выполнялись задачи линт и сборки). В настоящее время, когда возникает ошибка (например, ошибка lint), задача просмотра завершается.

Эта проблема хорошо известна и проста в разрешении. Типичным решением является: a) предотвращение ошибок или b) исправление поведения трубы.

а) Для gulp-tslint я мог бы использовать этот конфиг из своей домашней страницы:

gulp.task("invalid-noemit",() => 
    gulp.src("input.ts") 
     .pipe(tslint()) 
     .pipe(tslint.report("prose", { 
      emitError: false 
     })) 
); 

Но когда я включаю emitError флаг ошибка ворса регистрируется и все следующие задачи глотка выполняется (сборка, испытание) ,

b) Я мог бы также использовать gulp-plumber или вручную улавливать ошибки (см. here), но для всех этих известных решений одинаковое поведение, выполняются следующие задачи gulp (сборка, тестирование).

Что я хочу, так это то, что цепочка задач останавливается после ошибки (без сборки и теста после ошибки lint), но задача watch никогда не должна останавливаться. Как я могу это решить? Задачи Watcher выглядеть следующим образом:

// watcher 
gulp.task('watch', gulp.series('test', function doWatch() { 
    gulp.watch([ 
     config.paths.sourcePattern, 
     config.paths.testPattern, 
     'gulpfile.js' 
    ], gulp.parallel('test')); 
})); 

Вы можете найти полный gulpfile.jshere.

+0

Не могли бы вы опубликовать ваши часы задачу? –

+0

Я обновил вопрос с задачей часов. – ChrLipp

+0

- это то же самое, если вы используете gulp.series ('lint', 'build', 'test') для задачи просмотра, а не напрямую для других? – YOU

ответ

2

Причина, по которой останавливаются ваши часы, заключается в том, что объект err распространяется по цепочке обратного вызова. Вы должны помешать этому err достичь окончательного обратного вызова gulp.watch().

Вы можете сделать это, обернув обратный вызов, предоставленный gulp.watch() и никогда не передавая err объекта на оригинальную функции обратного вызова:

gulp.task('watch', function() { 
    gulp.watch([ 
     config.paths.sourcePattern, 
     config.paths.testPattern, 
     'gulpfile.js' 
    ], {ignoreInitial:false}, function(cb) { 
     gulp.series('lint', 'build', 'test')(function wrappedCb(err) { 
     cb(); // not passing err here 
    }); 
    }); 
}); 

Обратите внимание, что gulp.series('lint', 'build', 'test') фактически не выполняют задачи. Он просто возвращает новую функцию, которая принимает обратный вызов. Только когда эта новая функция вызывается, так как gulp.series('lint', 'build', 'test')() - фактически выполняемые задачи.

Я также добавил опцию ignoreInitial так, что часы выполняется один раз после запуска, который, кажется, что вы пытаетесь достичь с gulp.series('test', ...) в вашей watch задачи.

(в сторону: смотреть gulpfile.js бесполезно Изменения в gulpfile не вступят в силу до тех пор, пока перезапускать gulp watch Там нет никакого способа обойти это...)


Наконец, вы должны отвязать свои другие задачи, поэтому они не имеют явных зависимостей от других задач. Заманчиво перевести глоток 3.х задача, как это:

gulp.task('foo', ['bar'], function() { }); 

В задачу глотком 4.x так:

gulp.task('foo', gulp.series('bar', function() { })); 

Они внешне похожи на поверхности, но они совершенно разные под капотом. См. this article для получения дополнительной информации по этому вопросу.

Одна хорошая стратегия заключается в организации задач на две категории:

  1. Отдельные задачи, которые делают одну вещь и не зависят от других задач.
  2. Композитные задачи, которые выполняют несколько других задач последовательно или параллельно.

Следуя этому принципу ваши другие задачи могут быть переработан в этом:

gulp.task('lint', function() { 
    return gulp.src([ 
    config.paths.sourcePattern, 
    config.paths.testPattern 
    ]) 
    .pipe(tslint()) 
    .pipe(tslint.report('verbose', { 
    emitError: true, // we WANT to emit this err so our other tasks don't run 
    summarizeFailureOutput: true 
    })); 
}); 

gulp.task('build-app', function doBuildApp() { 
    /* ... */ 
}); 

gulp.task('build-test', function doBuildTest() { 
    /* ... */ 
}); 

gulp.task('build', gulp.series('lint', 'build-app', 'build-test')); 

gulp.task('test', gulp.series(function doPreTest() { 
    /* ... */ 
    }, function doTest() { 
    /* ... */ 
    }, function doPostTest() { 
    /* ... */ 
})); 
+0

Я знаю, как предотвратить остановку задачи просмотра, вопрос заключается в том, как предотвратить выполнение сборки и тестирования при возникновении ошибки lint (или при выполнении теста при возникновении ошибки сборки). – ChrLipp

+0

Вы действительно попробовали мое решение? Потому что он делает именно это. Задача 'lint' испускает объект' err', который предотвращает запуск 'build' и' test'. Но 'err' не передается' cb', что означает, что часы не останавливаются. –

+0

Я пробовал ваше решение. Единственное различие заключалось в том, что у меня не было ворса, сборки и тестирования в сериале, потому что lint является обязательным условием сборки и сборки, является предварительным условием теста. Поэтому я тестировал только серию, и это привело к выполнению всех шагов. Кстати, почему 'gulp.series()()' работает, не могли бы вы это объяснить? – ChrLipp

Смежные вопросы