【问题标题】:Grunt Watch Event with Grunt Copy for Only Changed FilesGrunt Watch 事件与 Grunt Copy 仅用于更改的文件
【发布时间】:2014-10-30 22:30:04
【问题描述】:

好的,我已经坚持了 2 周,所以希望这里的其他人遇到了这个问题。我正在尝试使用 Grunt 仅复制已更改的文件。我已经看到了很多关于如何使用 JSLINT 和 UGLIFY 执行此操作的示例,但没有关于如何使用 grunt-contrib-copy 执行此操作的具体示例。

当您注册监视事件并将文件名传递给复制子任务时,文件名是可访问的(我正在将其注销),但文件永远不会正确复制。

我希望这是一件我忽略的简单事情。有人可以看看我的代码,看看我做错了什么吗?

//Gruntfile.js:

module.exports = function(grunt) {
grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    options: {
        base: 'app',
        dist: 'dist',
    },

    copy: {
        changedFiles: {
            expand: true,
            dot: true,
            cwd: '<%= options.base %>',
            src: ['**/*.*'],
            dest: '<%= options.dist %>/'

        }
     },
    watch: {
        options: {
            nospawn: true,
            //debounceDelay: 1000,
        },
        css: {
            files: ['app/css/*.css',
                   'app/js/*.js'
                   ],
            tasks: ['copy:changedFiles'],

        }
    }    

});

grunt.event.on('watch', function(action, filepath, target){
    grunt.log.writeln('target: ', target + '\n filepath: ' + filepath + '\n action: has ' + action);
    grunt.config('copy.changedFiles.src', new Array(filepath) );
});

//load our copy task
grunt.loadNpmTasks('grunt-contrib-copy');

//load our watch task
grunt.loadNpmTasks('grunt-contrib-watch');

grunt.registerTask('copyChangedFiles', [
        'watch:css'
]);

};

基本上我的文件夹设置是这样的:

-app
| - css
| - js
-dist

我正在查看 app 文件夹并尝试复制 app 目录中更改的文件并将它们复制到 dist 目录。动态修改副本 src 似乎不起作用。

当使用 watch 而不是在 watch 事件上单独运行时,复制任务可以正常工作并复制每个文件,但我只对复制更改的文件感兴趣。

我也在我的手表事件中尝试了这种变化,但无济于事:

var copyDest = filepath.replace(grunt.config('copy.changedFiles.dest'), '');
var copyCwd = filepath.replace(grunt.config('copy.changedFiles.cwd'), '');
grunt.config('copy.changedFiles.cwd' , copyCwd);
grunt.config(['copy', 'changedFiles', 'src'] , [filepath]);

在使用 grunt copy 之前,有没有人成功地做到过这一点?还是我应该使用其他任务?我用 grunt-sync 尝试过同样的方法,但这似乎也不起作用。我被卡住了。

感谢您的帮助。

【问题讨论】:

    标签: gruntjs workflow grunt-contrib-watch grunt-contrib-copy


    【解决方案1】:

    您应该可以使用grunt-newer 包。我注意到的唯一一件事是,如果文件从源中删除并且当前位于副本的目标中,它不会执行删除操作。

    但是,对于大多数目的,这应该执行您正在寻找的任务。 Watch 将在文件更改时触发,仅当目标中的文件早于 src 时才会运行更新。

    注意:nospawn 已弃用,现在为 spawn。它是为了向后兼容而留下的。

    我不确定文件是否有意义:[&lt;pattern&gt;] 与复制任务中描述的src 模式不匹配。

    module.exports = function(grunt) {
    grunt.initConfig({
        options: {
            base: 'app',
            dist: 'dist',
        },
        copy: {
            changedFiles: {
                expand: true,
                dot: true,
                cwd: '<%= options.base %>',
                src: ['**/*.*'],
                dest: '<%= options.dist %>/'
            }
         },
        watch: {
            options: {
                //nospawn is depricated but kept for compatibility.  use spawn false instead
                spawn: false,
                cwd: '<%= options.base %>'
                //debounceDelay: 1000,
            },
            css: {
                //should match above
                files: ['**/*.*'],
                //On new file detection run copy:changedFiles
                tasks: ['newer:copy:changedFiles']
            }
        }     
    });
    
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-newer');
    
    grunt.registerTask('copyChangedFiles', ['watch:css']);
    
    };
    

    【讨论】:

      【解决方案2】:

      我能够使用这个 SO 答案:How to modify grunt watch tasks based on the file changed? 并对其进行修改以满足我的需要。我现在只能复制更改的文件。

      我的手表现在看起来像这样:

       var path = require('path');
      
       grunt.event.on('watch', function(action, filepath, target){
          grunt.log.writeln(target + ': ' + filepath + ' might have ' + action);
          var siteDirectory = path.dirname(filepath);
      
          //changes changed file source to that of the changed file
          var option = 'copy.changedFiles.src';
          var result = filepath;
          grunt.log.writeln(option + ' changed to ' + result);
          grunt.config(option, result);
      
          //customizes output directory so that file goes to correct place
          option = 'copy.changedFiles.dest';
          result = path.resolve(__dirname + '/dist');
          grunt.log.writeln(option + ' changed to ' + result);
          grunt.config(option, result);
      
      });
      

      现在运行grunt copyChangedFiles 将监视应用目录的更改,并且任何时候修改*.css*.js 文件,它都会将其复制到dist 目录。

      我真的希望这对其他人有所帮助,因为我花了两周时间才让它正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 2016-01-07
        • 2018-08-22
        • 2014-06-13
        相关资源
        最近更新 更多