Grunt Watch Rough Copy Event for Modified Files Only

Ok, I was stuck on this for 2 weeks, so hopefully someone else ran into this problem. I am trying to use Grunt to copy only files that have been modified. I have seen many examples of how to do this with JSLINT and UGLIFY, but there are no concrete examples of how to do this with grunt-contrib-copy.

When you register a viewing event and pass the file name into the copy subtask, the file name is available (I exit), but the file is never copied properly.

I hope this is a simple thing that I do not notice. Can someone please take a look at my code and see what I am doing wrong?

//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' ]); }; 

Basically, setting up my folder is as follows:

 -app | - css | - js -dist 

I am browsing the application folder and trying to copy files that change in the application directory and copy them to the dist directory. Dynamically changing the src copy does not seem to work.

The task of copying at startup by itself with the clock, and not on the hourly event, works just fine and copies all the files, but I'm only interested in copying files that change.

I also tried a variant of this in my watch event, but to no avail:

 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]); 

Has anyone ever done this before using a grunted copy? Or is there another task that I should use? I tried the same with grunt-sync, and that didn't work either. I am stuck.

Thanks for the help.

+5
source share
2 answers

I was able to use this SO answer: How to change file-based grunt view tasks? and change it according to my needs. Now I can copy only those files that have changed.

My watch now looks like this:

  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); }); 

Now working grunt copyChangedFiles will look at the application directory for changes, and at any time when the *.css or *.js file is modified, it will copy it to the dist directory.

I really hope this helps someone else since I spent two weeks for this to work properly.

+1
source

You can use grunt-newer . The only thing I noticed about this is that it does not perform the delete action if the files are deleted from the source and are currently at the destination of the copy.

However, for most purposes, this should accomplish the task you are looking for. The clock will start when the file changes, the newer will only work if the files in the destination are older than src .

Note: nospawn deprecated and now spawn . It was left for backward compatibility.

I'm not sure if this makes sense for files: [<pattern>] does not match the src pattern described in the copy task.

 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']); }; 
+1
source

Source: https://habr.com/ru/post/1205903/


All Articles