Gulps gulp.watch не запускается для новых или удаленных файлов?


151

Следующая задача Gulpjs отлично работает при редактировании файлов в глобальном совпадении:

// watch task.
gulp.task('watch', ['build'], function () {
    gulp.watch(src + '/js/**/*.js', ['scripts']);
    gulp.watch(src + '/img//**/*.{jpg,jpeg,png,gif}', ['copy:images']);
    gulp.watch(src + '/less/*.less', ['styles']);
    gulp.watch(src + '/templates/**/*.{swig,json}', ['html']);
});

// build task.
gulp.task('build', ['clean'], function() {
    return gulp.start('copy', 'scripts', 'less', 'htmlmin');
});

Однако это не работает (это не срабатывает) для новых или удаленных файлов. Я что-то упускаю?

РЕДАКТИРОВАТЬ : даже используя плагин grunt-watch, он, кажется, не работает:

gulp.task('scripts', function() {
    return streamqueue(
        { objectMode: true },
        gulp.src([
            vendor + '/jquery/dist/jquery.min.js',
            vendor + '/bootstrap/dist/js/bootstrap.min.js'
        ]),
        gulp.src([
            src + '/js/**/*.js'
        ]).pipe(plugins.uglify())
    )
    .pipe(plugins.concat(pkg.name + '.min.js'))
    .pipe(gulp.dest(dest + '/js/'));
});

gulp.task('watch', ['build'], function () {
    plugins.watch({glob: src + '/js/**/*.js'}, function () {
        gulp.start('scripts');
    });
});

РЕДАКТИРОВАТЬ : Решено, это была эта проблема . Глобусы, начинающиеся с ./(это было значение src), кажется, не работает банкомат.


2
Было бы здорово, если бы вы изменили принятый ответ на ответ от Нестора Уркизы. Это реальный ответ здесь, а не добавление дополнительного плагина
Джастин Ноэль

ответ на @alexk был самым простым, и не требует добавления gulp-watch, напримерgulp.watch('js/**/*.js', {cwd: src}, ['scripts']);
Лошадь

Ответы:


130

Редактировать: По-видимому gulp.watch, теперь работает с новыми или удаленными файлами. Это не когда вопрос был задан.

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


Вы ничего не пропускаете. gulp.watchне работает с новыми или удаленными файлами. Это простое решение, предназначенное для простых проектов.

Чтобы получить файл наблюдение , которое может искать новые файлы, использовать в gulp-watchплагин , который является гораздо более мощным. Использование выглядит так:

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

// in a task
watch({glob: <<glob or array of globs>> })
        .pipe( << add per-file tasks here>> );

// if you'd rather rerun the whole task, you can do this:
watch({glob: <<glob or array of globs>>}, function() {
    gulp.start( <<task name>> );
});

Лично я рекомендую первый вариант. Это позволяет значительно ускорить процессы для каждого файла. Он отлично работает при разработке с livereload, если вы не объединяете файлы.

Вы можете обернуть свои потоки либо используя мою lazypipeбиблиотеку , либо просто используя функцию и stream-combinerвот так:

var combine = require('stream-combiner');

function scriptsPipeline() {
    return combine(coffeeescript(), uglify(), gulp.dest('/path/to/dest'));
}

watch({glob: 'src/scripts/**/*.js' })
        .pipe(scriptsPipeline());

ОБНОВЛЕНИЕ 15 октября 2014

Как указывает @pkyeck ниже, очевидно, что версия 1.0 gulp-watchнемного изменила формат, поэтому приведенные выше примеры теперь должны быть:

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

// in a task
watch(<<glob or array of globs>>)
        .pipe( << add per-file tasks here>> );

// if you'd rather rerun the whole task, you can do this:
watch(<<glob or array of globs>>, function() {
    gulp.start( <<task name>> );
});

и

var combine = require('stream-combiner');

function scriptsPipeline() {
    return combine(coffeeescript(), uglify(), gulp.dest('/path/to/dest'));
}

watch('src/scripts/**/*.js')
        .pipe(scriptsPipeline());

Спасибо за помощь, но до сих пор не могу заставить его работать. Я новичок в Gulp (я использовал Grunt пару раз) и, возможно, моя главная задача не так ... не знаю. Смотрите мой обновленный вопрос.
Гремо

18
github.com/floatdrop/gulp-watch/issues/1 глобусы, начинающиеся с './', не излучающие. Моя переменная src в точности '- /'. Нашел проблему! Спасибо!
Гремо

1
Хорошо поймать эту ошибку. Надеюсь, это поможет, если кто-нибудь еще столкнется с этим!
Превосходно

@JHannes На что ты отвечаешь? Вот что объясняет этот ответ.
Чрезвычайный рев

2
gulp.start - это вызов непубличного метода API. Есть ли другой способ выполнения задач?
Ричард Коллетт

87

И то gulp.watch()и другое require('gulp-watch')()сработает для новых / удаленных файлов, однако, нет, если вы используете абсолютные каталоги. В моих тестах я не использовал "./"для относительных каталогов BTW.

Оба не сработают, если будут удалены целые каталоги.

   var watch = require('gulp-watch');
   //Wont work for new files until gaze is fixed if using absolute dirs. It  won't trigger if whole directories are deleted though.
   //gulp.watch(config.localDeploy.path + '/reports/**/*', function (event) {

   //gulp.watch('src/app1/reports/**/*', function (event) {
   // console.log('*************************** Event received in gulp.watch');
   // console.log(event);
   // gulp.start('localDeployApp');
   });

   //Won't work for new files until gaze is fixed if using absolute dirs. It  won't trigger if whole directories are deleted though. See https://github.com/floatdrop/gulp-watch/issues/104
   //watch(config.localDeploy.path + '/reports/**/*', function() {

   watch('src/krfs-app/reports/**/*', function(event) {
      console.log("watch triggered");
      console.log(event);
      gulp.start('localDeployApp');
   //});

2
Отличный и простой ответ.
Эдгар Мартинес

3
да - так много примеров глотка начинаются с ./их путей - на самом деле это кажется плохой практикой - github.com/floatdrop/gulp-watch/issues/1
rmorse

1
Спасибо тебе за это. Я просто ломал голову, пытаясь заставить gulp-watchработать должным образом запуск новых или удаленных файлов. Незачем! gulp.watchЯвляется ли это. Удаление всех ./из путей прояснило проблемы. Потрясающие.
The Qodesmith

2
Вероятно, это должен быть правильный ответ - на самом деле не хотелось устанавливать другой плагин для просмотра. Убрал ./ со всех моих шаров и работал отлично! Спасибо!
Неджи

1
Это лучший ответ, дополнительный модуль не требуется или понимание сумасшедшего синтаксиса.
Realappie

57

Если srcэто абсолютный путь (начиная с /), ваш код не будет обнаруживать новые или удаленные файлы. Однако есть еще способ:

Вместо того:

gulp.watch(src + '/js/**/*.js', ['scripts']);

записывать:

gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);

и это будет работать!


12
{ cwd: src }Намек был моим решением. Большое спасибо!
wiredolphin

1
Большое спасибо @alexk, {cwd: src} решил мою проблему.
kaxi1993

@DanielTonon ты по ошибке вставил в массив файлов? должно быть прямым параметромwatch
Лошадь

Это не может быть в массиве? Ну, это отстой. Как насчет исключений? Невозможно выполнить поглощение без исключений, не помещая исходные файлы в массив.
Даниэль Тонон

4
Отличный ответ. Чтобы добавить дальше, если вы не хотите изменять каждый шаблон глобуса, просто добавьте {cwd:'./'}и оставьте шаблон глобуса таким, каким он сталgulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
Akash

7

Для глобусов должен быть указан отдельный базовый каталог, и это базовое местоположение не должно указываться в самом глобусе.

Если у вас есть lib/*.js, он будет смотреть под текущим рабочим каталогом, которыйprocess.cwd()

Gulp использует Gaze для просмотра файлов, и в документации по Gulp API мы видим, что мы можем передать определенные параметры Gaze функции наблюдения:gulp.watch(glob[, opts], tasks)

Теперь в документе Gaze мы можем найти, что текущим рабочим каталогом (glob base dir) является cwdвариант.

Что приводит нас к ответу Алекса: gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);


3

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

Вот пример того, как эта функция используется:

watch({
    root: config.src.root,
    match: [{
      when: 'js/**',
      then: gulpStart('js')
    }, {
      when: '+(scss|css)/**',
      then: gulpStart('css')
    }, {
      when: '+(fonts|img)/**',
      then: gulpStart('assets')
    }, {
      when: '*.+(html|ejs)',
      then: gulpStart('html')
    }]
  });

Я должен отметить, что gulpStart - также удобная функция, которую я сделал.

А вот актуальный модуль часов.

module.exports = function (options) {
  var path = require('path'),
      monocle = require('monocle'),
      minimatch = require('minimatch');

  var fullRoot = path.resolve(options.root);

  function onFileChange (e) {
    var relativePath = path.relative(fullRoot, e.fullPath);

    options.match.some(function (match) {
      var isMatch = minimatch(relativePath, match.when);
      isMatch && match.then();
      return isMatch;
    });
  }

  monocle().watchDirectory({
    root: options.root,
    listener: onFileChange
  });
};

Довольно просто, а? Все это можно найти в моем наборе для начинающих: https://github.com/chrisdavies/gulp_starter_kit


1
Эй, приятель, мало людей дали реквизиты для этого! Это работает как шарм, большое спасибо. (В ответе не учитывается, что делает «gulpStart», поэтому может возникнуть путаница, если кому-то интересно, просто перейдите по ссылке и utilsперейдите в папку)
Augie Gardner


0

Вы должны использовать «gulp-watch» для новых / переименованных / удаленных файлов вместо gulp.watch

var gulpwatch = require('gulp-watch');
var source = './assets',  
destination = './dest';
gulp.task('copy-changed-assets', function() {
    gulpwatch(source+'/**/*', function(obj){
        gulp.src( obj.path, { "base": source})
        .pipe(gulp.dest(destination));
    });
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.