【问题标题】:How to run a task ONLY on modified file with Gulp watch如何使用 Gulp watch 仅在修改后的文件上运行任务
【发布时间】:2014-05-27 13:31:14
【问题描述】:

我有我在 gulpfile 中使用的当前 gulp 任务。路径来自 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() 将仅在此图像上运行,而不是全部运行。

再次一切正常,但运行时间真的很长。

谢谢。

【问题讨论】:

    标签: gulp gulp-watch


    【解决方案1】:

    “gulp-changed”不是这样做的最佳解决方案,因为它只监视“buildType”文件夹中的修改文件。

    改用gulp-cached。

    【讨论】:

    • 这让世界变得与众不同,而且非常容易实施。谢谢!
    • 正是我想要的。谢谢!
    • 值得注意的是,gulp-cached 的缓存在第一次运行时是空的。所以,如果你依赖它,你第一次运行 watch 任务会影响所有给它的文件。在某些情况下没什么大不了的,但它让我措手不及。
    【解决方案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(path) {
          gulp
            .src(path)
            .pipe(imagemin({
                progressive: true,
                svgoPlugins: [{removeViewBox: false}],
                use: [pngcrush()]
            }))
            .pipe(gulp.dest(buildType))
            .pipe(connect.reload());
      });
    

    【讨论】:

    • 如果你使用这种方法,那么你将不得不自己处理文件的相对目标路径,因为 gulp 不会自己做.. 至少它在最后可以工作:)
    • 这是完美的。我只需要该模式来仅编辑更改的特定文件。
    • gulp 网站says,“你可能不会使用这个功能,”当它看起来真的很有用时,这真是太奇怪了。我希望他们不要那样做。让我觉得我不应该使用它。
    【解决方案3】:

    无需插件,只需 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'));
    });
    

    【讨论】:

    • 当我这样做时,我得到无效的 glob 参数错误:未定义。
    • 你的任务名称是什么,试试改一下?
    • 'change', function(obj) 中的 "obj" 似乎有点误导。使用更改文件的路径(字符串)调用回调。
    • 是的,把参数名改成fileName。
    【解决方案4】:

    自 4.0 版起,Gulp 原生支持增量构建,无需任何插件。这是取自project README的示例:

    const paths = {
      ...
      images: {
        src: 'src/images/**/*.{jpg,jpeg,png}',
        dest: 'build/img/'
      }
    }
    
    function images() {
      return gulp.src(paths.images.src, {since: gulp.lastRun(images)})
        .pipe(imagemin())
        .pipe(gulp.dest(paths.images.dest));
    }
    
    function watch() {
      gulp.watch(paths.images.src, images);
    }
    

    【讨论】:

      【解决方案5】:

      我可以建议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
      }
      

      【讨论】:

        【解决方案6】:

        是的,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());
        });
        

        【讨论】:

          【解决方案7】:

          这是一个真实的示例,我一直使用它来执行此操作,而无需任何其他软件包。我使用它来缩小、重命名和编译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 );
          

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

          【讨论】:

          • 这是最直接的答案,它不依赖于处理每个文件并与缓存版本进行比较。谢谢!
          【解决方案8】:

          在任务或回调中,你会有一个事件参数,它有一个类型属性,它会告诉你文件是否被添加、删除或更改。最好的办法是根据你的任务来利用它。

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

          【讨论】:

            【解决方案9】:

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

            const imageFilePattern = '/src/path/to/input';
            
            function images() {
              getImagesTask(imageFilePattern);
            }
            
            function imagesTask(src) {
              return gulp.src(src)
                .pipe(imagemin())
                .pipe(gulp.dest('dest'));
            }
            

            现在您可以轻松地将监视任务定义为仅处理更改的文件:

            function watch() {
              return gulp.watch(imageFilePattern).on("change", imagesTask);
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-01-08
              • 1970-01-01
              • 2017-08-01
              • 2021-04-03
              • 2013-07-29
              相关资源
              最近更新 更多