Как запустить задачу ТОЛЬКО на измененном файле с помощью Gulp watch

У меня есть текущая задача gulp, которую я использую в gulpfile. Путь из config.json и все работает отлично:

//Some more code and vars...

gulp.task('watch', function() {
    gulp.watch([config.path.devfolder+"/**/*.png", config.path.devfolder+"/**/*.jpg", config.path.devfolder+"/**/*.gif", config.path.devfolder+"/**/*.jpeg"], ['imagemin-cfg']);
})

//Some more code ...

gulp.task('imagemin-cfg', function () {
    return gulp.src([config.path.devfolder+"/**/*.png", config.path.devfolder+"/**/*.jpg", config.path.devfolder+"/**/*.gif", config.path.devfolder+"/**/*.jpeg"], {read: false})
        .pipe(imagemin({
            progressive: true,
            svgoPlugins: [{removeViewBox: false}],
            use: [pngcrush()]
        }))
        .pipe(gulp.dest(buildType))
        .pipe(connect.reload());
});

Но у меня все еще есть проблема, количество изображений в моем проекте огромно, и эта задача занимает много времени. Я ищу способ запустить свою задачу ТОЛЬКО на измененных файлах. Если у меня есть изображение или его изменение, imagemin() будет работать только на этом изображении, а не на всех.

Снова все работает отлично, но время работы очень велико.

Спасибо.

Ответ 1

"gulp -changed" не является лучшим решением для этого, потому что он смотрит только измененный файл в папке "buildType".

Попробуйте gulp-cached.

Ответ 2

Другой вариант - использовать опцию gulp.watch on ( "change" ).

gulp
  .watch([config.path.devfolder+"/**/*.png", config.path.devfolder+"/**/*.jpg", config.path.devfolder+"/**/*.gif", config.path.devfolder+"/**/*.jpeg"])
  .on("change", function(file) {
      gulp
        .src(file.path)
        .pipe(imagemin({
            progressive: true,
            svgoPlugins: [{removeViewBox: false}],
            use: [pngcrush()]
        }))
        .pipe(gulp.dest(buildType))
        .pipe(connect.reload());
  });

Ответ 3

С gulp.watch вы можете настроить таргетинг на измененный файл следующим образом.

gulp.watch(["src/**/*"], function (obj) {
 return gulp.src(obj.path, {"base": "src/"})
 .pipe(gulp.dest("dest"));
});

Изменение: для Gulp v4:

const { watch, src, dest } = require('gulp');

var watcher = watch(["src/**/*"]);
watcher.on('change', function(obj){
    return src(obj.path, {base: 'src/'})
        .pipe(dest('dest'));
});

Ответ 4

Могу ли я предложить gulp-newy, в котором вы можете манипулировать путем и именем файла в своей собственной функции. Затем просто используйте функцию в качестве обратного вызова к newy(). Это дает вам полный контроль над файлами, которые вы хотели бы сравнить.

Это позволит сравнивать 1:1 или многие к 1.

newy(function(projectDir, srcFile, absSrcFile) {
  // do whatever you want to here. 
  // construct your absolute path, change filename suffix, etc. 
  // then return /foo/bar/filename.suffix as the file to compare against
}

введите описание изображения здесь

Ответ 5

Да, gulp -changed делает именно это:

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

gulp.task('imagemin-cfg', function () {
return gulp.src([config.path.devfolder+"/**/*.png", config.path.devfolder+"/**/*.jpg", config.path.devfolder+"/**/*.gif", config.path.devfolder+"/**/*.jpeg"], {read: false})
    .pipe(changed(buildType))
    .pipe(imagemin({
        progressive: true,
        svgoPlugins: [{removeViewBox: false}],
        use: [pngcrush()]
    }))
    .pipe(gulp.dest(buildType))
    .pipe(connect.reload());
});

Ответ 6

Вот реальный пример, который я использую все время, чтобы сделать это без каких-либо дополнительных пакетов. Я использую это для минимизации, переименования и компиляции любого файла .js в каталоге js. Скомпилированные файлы сохраняются в каталоге dist с добавлением .min перед расширением.

// Compile JS
var compileJS = function( file ) {
    var currentDirectory = process.cwd() + '/';
    var modifiedFile = file.path.replace( currentDirectory, '' );

    gulp.src( modifiedFile )
        .pipe( uglify() )
        .pipe( rename( {
            suffix: ".min"
        } ) )
        .pipe( livereload() )
        .pipe( gulp.dest( 'dist' ) );
};

// Watch for changes
gulp.watch( 'js/*.js', [ 'js' ] ).on( "change", compileJS );

Приведенные выше ответы казались мне частично неполными и немного неясными для меня, надеюсь, это поможет всем, кто ищет простой пример.

Ответ 7

В задаче или обратном вызове у вас будет параметр события, у которого есть свойство type, которое сообщит вам, был ли файл добавлен, удален или изменен. Лучше всего использовать это в условиях вашей задачи.

gulp.watch('path to watch', function(event){
  if(event.type === 'changed') { 
    gulp.start('your:task');
  }
};