使用Grunt Watch事件和Grunt Copy仅复制更改的文件

7

好的,我已经在这个问题上卡了两周了,所以希望这里有其他人遇到过这个问题。我正在尝试使用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目录。动态修改复制源似乎不起作用。
仅使用watch运行复制任务而不在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,但似乎也不起作用。我卡住了。

谢谢你的帮助。

2个回答

1
我能使用这个SO的答案:如何基于更改的文件修改grunt watch任务?,并将其修改以适应我的需求。现在我能够只复制更改的文件。
我的watch现在看起来是这样的:
 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目录中。希望这能帮助其他人,因为我花了两周时间才使它正常工作。

1
您应该能够使用grunt-newer包。我注意到的唯一问题是,如果文件从源中删除并且当前在复制目标中,则它不会执行删除操作。
但是,对于大多数情况,这应该可以完成你要找的任务。当文件更改时,将触发监视,只有当目标中的文件早于src时,新文件才会运行。
注意:nospawn已被弃用,现在为spawn。它保留了向后兼容性。
我不确定文件:[<pattern>]与复制任务中描述的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']);

};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接