GULP: изменить просматриваемый файл на месте, не вызывая бесконечный цикл

Я пытаюсь использовать Gulp и JSC для предотвращения запаха кода. Я также хочу использовать часы, чтобы это происходило при внесении изменений. Проблема, с которой я сталкиваюсь, заключается в том, что jscs изменяет исходный файл, который отслеживается. Это приводит к тому, что gulp входит в бесконечный цикл jscs, модифицируя файл, а затем наблюдает за изменениями и снова и снова запускает jscs...

const gulp = require('gulp');

gulp.task('lint', function() {
    return gulp.src('/src/**/*.js')
        .pipe(jscs({
            fix: true
        }))
        .pipe(jscs.reporter())
        .pipe(gulp.dest('/src'));
});

gulp.task('watch', function() {
    gulp.watch('/src/**/*.js', ['lint']);
});

1 ответ

Обычно плохая идея переопределять исходные файлы из задачи gulp. Любые редакторы /IDE, в которых эти файлы открыты, могут или не могут справиться с этим изящно. Как правило, лучше записывать файлы в отдельный dist папка.

При этом есть два возможных решения:

Решение 1

Вам нужно остановить gulp-jscs плагин запускается во второй раз и снова записывает файлы, тем самым предотвращая бесконечный цикл, с которым вы работаете. Для достижения этого все, что вам нужно сделать, это добавить gulp-cached на ваш lint задача:

var cache = require('gulp-cached');

gulp.task('lint', function() {
  return gulp.src('/src/**/*.js')
    .pipe(cache('lint'))
    .pipe(jscs({
        fix: true
    }))
    .pipe(cache('lint'))
    .pipe(jscs.reporter())
    .pipe(gulp.dest('/src'));
});

Первый cache() гарантирует, что только те файлы на диске, которые были изменены с момента последнего вызова lint проходят через. Второй cache() гарантирует, что только файлы, которые были на самом деле исправлены jscs() записываются на диск в первую очередь.

Недостатком этого решения является то, что lint задание все еще выполняется дважды. Это не имеет большого значения, так как во время второго запуска файлы на самом деле не помечаются. gulp-cache предотвращает это Но если вы абсолютно хотите убедиться, что lint запускается только когда есть другой путь.

Решение 2

Сначала вы должны использовать gulp-watch плагин вместо встроенного gulp.watch() (это потому, что он использует высший chokidar библиотека вместо gaze).

Тогда вы можете написать себе простую pausableWatch() функционировать и использовать это в вашем watch задача:

var watch = require('gulp-watch');

function pausableWatch(watchedFiles, tasks) {
  var watcher = watch(watchedFiles, function() {
    watcher.close();
    gulp.start(tasks, function() {
      pausableWatch(watchedFiles, tasks);
    });
  });
}

gulp.task('watch', function() {
  pausableWatch('/src/**/*.js', ['lint']);
});

В приведенном выше watcher остановлен до lint задание начинается. любой .js файлы, записанные во время lint Поэтому задача не будет вызывать watcher, После lint задание выполнено, watcher снова запускается.

Недостатком этого решения является то, что если вы сохраните .js файл в то время как lint задача выполняется, что изменение не будет принято watcher (так как он был остановлен). Вы должны сохранить .js файл после lint задание выполнено (когда watcher был начат снова).

Другие вопросы по тегам