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

Однак це не працює (це не спрацьовує) для нових або видалених файлів. Щось мені не вистачає?

EDIT : навіть за допомогою плагіну 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');
    });
});

EDIT : Вирішено, саме це питання . Глобуси, що починаються з ./(це було значення 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>> );
});

Особисто я рекомендую перший варіант. Це дозволяє значно швидше обробляти файли. Він чудово працює під час розробки з завантаженням, доки ви не об'єднуєте жодних файлів.

Ви можете завершити свої потоки або за допомогою моєї 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), і, можливо, моє головне завдання - це неправильно ... dunno. Дивіться моє оновлене запитання.
gremo

18
github.com/floatdrop/gulp-watch/isissue/1 глобуси, починаючи з "./", не випромінюючи Моя змінна src рівно "- /". Знайшли проблему! Дякую!
gremo

1
Гарний вилов на пошуку цього клопа. Сподіваємось, це допоможе, якщо хтось інший натрапить на нього!
OverZealous

@JHannes На що ти відповідаєш? Ось що пояснює ця відповідь.
OverZealous

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
yup - так багато прикладів з глотком там починаються ./на їх шляху - насправді це здається поганою практикою - github.com/floatdrop/gulp-watch/isissue/1
rmorse

1
Дякую за це. Я просто ламав мозок, намагаючись gulp-watchнормально працювати, щоб запустити нові файли чи видалені файли. Нема потреби! gulp.watchробить це. Видалення всіх ./шляхів очистило проблеми. Дивовижно.
The Qodesmith

2
Це, мабуть, буде правильною відповіддю - не дуже хотілося встановити інший плагін для перегляду. Вилучив ./ з усіх моїх кульок і працював ідеально! Дякую!
0Неджи

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']);
Акаш,

7

Для глобусів повинен бути вказаний окремий базовий каталог, і місце розташування бази не повинно вказуватися в самому глобусі.

Якщо у вас є lib/*.js, він перегляне поточний робочий режим, який єprocess.cwd()

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

Тепер у документі Gaze ми можемо виявити, що поточний робочий dir (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.