Gruntjs: How to make copy task to copy only changed files on watch

12,267

Solution 1

Use grunt-sync (https://npmjs.org/package/grunt-sync) instead of grunt-contrib-copy, and watch the directories you want to be synced.

Update - here's an example:

grunt.initConfig({
  sync: {
    copy_resources_to_www: {
      files: [
        { cwd: 'src', src: 'img/**', dest: 'www' },
        { cwd: 'src', src: 'res/**', dest: 'www' }
      ]
    }
  }
});

cwd means current working directory. copy_resources_to_www is just a label.

Solution 2

You need to point grunt.config to the correct property in your config:

grunt.event.on('watch', function(action, filepath) {
  var cfgkey = ['copy', 'devTmpl', 'files'];
  grunt.config.set(cfgkey, grunt.config.get(cfgkey).map(function(file) {
    file.src = filepath;
    return file;
  }));
});
Share:
12,267
GnrlBzik
Author by

GnrlBzik

short to none

Updated on June 03, 2022

Comments

  • GnrlBzik
    GnrlBzik almost 2 years

    So on grunt-contrib-watch plugin info page, there is an example on how to make jshint run only for changed file.

    grunt.initConfig({
      watch: {
        scripts: {
          files: ['lib/*.js'],
          tasks: ['jshint'],
          options: {
            nospawn: true,
          },
        },
      },
      jshint: {
        all: ['lib/*.js'],
      },
    });
    
    grunt.event.on('watch', function(action, filepath) {
      grunt.config(['jshint', 'all'], filepath);
    });
    

    I have not tested example it self. But took this and applied to my copy task, unsuccessfully. grunt-contrib-copy task set up to copy images and templates for my angular project. And I would be happy to know if I can make this work for copy task and if I can, what am I doing wrong.

    Thank you so much.

    Here is my stripped out Gruntfile.js.

    // Build configurations.
    module.exports = function(grunt){
    
      // Project configuration.
        grunt.initConfig({
    
          pkg: grunt.file.readJSON('package.json'),
    
          // Copies directories and files from one location to another.
          copy: {
            // DEVELOPMENT
            devTmpl: {
              files: [{
                cwd     : 'src/tpl/',
                src     : ['**/*'], 
                dest    : 'app/tpl/',
                flatten : false,
                expand  : true
              }]
            },
            devImg: {
              files: [{
                cwd     : 'src/img/',
                src     : ['**/*'], 
                dest    : 'app/img/', 
                flatten : false,
                expand  : true
              }]
            }
          },
    
          // Watch files for changes and run tasks 
          watch: {
            // Templates, copy
            templates: {
              files : 'src/tpl/**/*',
              tasks : ['copy:devTmpl'],
              options: {
                nospawn: true,
              }
            },
            // Images, copy
            images: {
              files : 'src/img/**/*',
              tasks : ['copy:devImg'],
              options: {
                nospawn: true,
              }
            }
          }
    
        });
    
      // Watch events
        grunt.event.on('watch', function(action, filepath) {
          // configure copy:devTmpl to only run on changed file
          grunt.config(['copy','devTmpl'], filepath);
          // configure copy:devImg to only run on changed file
          grunt.config(['copy','devImg'], filepath);
        });
    
      // PLUGINS:
        grunt.loadNpmTasks('grunt-contrib-copy');
    
    
      // TASKS:
    
        /* DEV: Compiles the app with non-optimized build settings, places the build artifacts in the dist directory, and watches for file changes.
        run: grunt dev */
        grunt.registerTask('dev', 'Running "DEVELOPMENT", watching files and compiling...', [
          'default',
          'watch'
        ]);
    
        /* DEFAULT: Compiles the app with non-optimized build settings and places the build artifacts in the dist directory.
        run: grunt */
        grunt.registerTask('default', 'Running "DEFAULT", compiling everything.', [
          'copy:devTmpl',
          'copy:devImg'
        ]);
    
    }
    
  • Kyle Robinson Young
    Kyle Robinson Young almost 11 years
    Oh my mistake, I thought you could set config that way. I edited the answer. Try that one instead.
  • GnrlBzik
    GnrlBzik almost 11 years
    : / nope i guess i wil have to leave with script copying all files : )
  • Dan
    Dan over 10 years
    @GnrlBzik don't give up so fast!
  • GnrlBzik
    GnrlBzik over 10 years
    Thanks @Dan. I optimized my grunt task so its not all that bad, but i will be doing revisiting my grunt built script soon, will scratch my head then.
  • lordB8r
    lordB8r over 10 years
    would be nice if the docs had something a bit more useful to read. grunt-sync might be nice, but the examples are very obtuse.
  • wawiwa
    wawiwa about 5 years
    This may prove helpful if you're livereload(ing) to a dist folder, and want to sync your dist folder to another separate folder: webfoobar.com/node/78