如何使用Gulp watch仅在修改过的文件上运行任务

如何使用Gulp watch仅在修改过的文件上运行任务,gulp,gulp-watch,Gulp,Gulp Watch,我有当前的吞咽任务,我在吞咽文件中使用它。路径来自config.json,一切都可以完美运行: //还有一些代码和变量。。。 吞咽任务('watch',function(){ gulp.watch([config.path.devfolder+“/***.png”、config.path.devfolder+“/***.jpg”、config.path.devfolder+“/***.gif”、config.path.devfolder+“/***.jpeg”]、['imagemin-cfg']

我有当前的吞咽任务,我在吞咽文件中使用它。路径来自config.json,一切都可以完美运行:

//还有一些代码和变量。。。
吞咽任务('watch',function(){
gulp.watch([config.path.devfolder+“/***.png”、config.path.devfolder+“/***.jpg”、config.path.devfolder+“/***.gif”、config.path.devfolder+“/***.jpeg”]、['imagemin-cfg']);
})
//更多的代码。。。
吞咽任务('imagemin-cfg',函数(){
返回gulp.src([config.path.devfolder+“/***.png”、config.path.devfolder+“/***.jpg”、config.path.devfolder+“/***.gif”、config.path.devfolder+“/***.jpeg”],{read:false})
.管道(最小值)({
进步:是的,
svgoPlugins:[{removeViewBox:false}],
用法:[pngcrush()]
}))
.管道(大口目的地(建筑类型))
.pipe(connect.reload());
});
但我仍然有一个问题,我的项目中的图像数量巨大,这项任务需要很长时间。我正在寻找一种只在修改过的文件上运行任务的方法。如果我有图像或对其进行了修改,
imagemin()
将仅在该图像上运行,而不是在所有图像上运行

再一次,一切都运行得非常好,但运行时间确实很长


谢谢。

是的,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());
});
“GulpChanged”并不是最好的解决方案,因为它只查看“buildType”文件夹中的修改字段

请改为尝试。

我建议您可以在自己的函数中操作路径和文件名。然后,只需将该函数用作对
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
}

另一个选项是使用gulp.watch on(“更改”)选项


在任务或回调中,您将有一个事件参数,该参数有一个type属性,它将告诉您文件是否已添加、删除或更改。最好的办法是在你的任务中有条件地利用它

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

不需要插件,只需gulp.watch即可实现

使用gulp.watch,您可以像这样针对更改的文件

gulp.watch(["src/**/*"], function (obj) {
 return gulp.src(obj.path, {"base": "src/"})
 .pipe(gulp.dest("dest"));
});
编辑:对于Gulp v4.0.2-现在已修复:

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

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

这里有一个真实的例子,我一直在使用它,而不需要任何额外的包。我使用它来缩小、重命名和编译
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 );

上面的回答似乎部分不完整,对我来说有点不清楚,希望这对其他寻找基本示例的人有所帮助。

定义主任务,以便它接受
.src()
输入模式的参数。定义一个包装函数,为任务传递一个默认的src值,这样您仍然可以像
gulpimages
那样直接调用它:

const-imageFilePattern='/src/path/to/input';
函数图像(){
getImagesTask(imageFilePattern);
}
函数imagesTask(src){
回灌量src(src)
.pipe(imagemin())
.管道(大口目的地(“目的地”);
}
现在,您可以轻松定义“监视”任务以仅处理更改的文件:

函数监视(){
返回gulp.watch(imageFilePattern).on(“更改”,imagesTask);
}

自4.0版以来,增量版本在Gulp中本机支持,无需任何插件。以下是从以下内容中选取的示例:

const路径={
...
图像:{
src:'src/images/***.{jpg,jpeg,png}',
dest:'build/img/'
}
}
函数图像(){
返回gulp.src(path.images.src,{自:gulp.lastRun(images)})
.pipe(imagemin())
.管道(吞咽目标(路径图像目标));
}
函数监视(){
gulp.watch(path.images.src,images);
}

这带来了巨大的不同,而且非常容易实现。谢谢正是我想要的。非常感谢。值得注意的是,gulp cached的缓存在第一次运行时是空的。因此,如果您依赖它,第一次运行监视任务将影响提供给它的所有文件。对于某些场景来说,这不是什么大不了的事情,但它让我措手不及。如果使用这种方法,那么您必须自己处理文件的相对目标路径,因为gulp本身不会处理。。至少它在结尾起作用:)@TimMalone我不记得了。但我会在7个月后告诉你。请继续关注。@atilkan已经7个月了-你现在能告诉我们吗?@AlexL这只是一个讽刺。这太完美了。我只需要该模式来编辑被更改的特定文件。执行此操作时,我得到无效的全局参数错误:未定义。任务名称是什么,请尝试更改它。
“更改”中的“obj”,函数(obj)
似乎有点误导。回调是通过更改文件的路径(字符串)调用的。如果为True,则将参数名称更改为
fileName
。这是最直接的答案,它不依赖于处理每个文件并与缓存版本进行比较。谢谢这应该是公认的答案
// 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 );