-->

Grunt watch: compile only one file not all

2019-02-17 00:53发布

问题:

I have grunt setup to compile all of my coffee files into javascript and maintain all folder structures using dynamic_mappings which works great.

coffee: {
  dynamic_mappings: {
    files: [{
      expand: true,
      cwd: 'assets/scripts/src/',
      src: '**/*.coffee',
      dest: 'assets/scripts/dest/',
      ext: '.js'
    }]
  }
}

What I would like to do is then use watch to compile any changed coffee file and still maintain folder structure. This works using the above task with this watch task:

watch: {
  coffeescript: {
    files: 'assets/scripts/src/**/*.coffee',
    tasks: ['coffee:dynamic_mappings']
  }
}

The problem is that when one file changes it compiles the entire directory of coffee into Javascript again, it would be great if it would only compile the single coffee file that was changed into Javascript. Is this naturally possible in Grunt or is this a custom feature. The key here is it must maintain the folder structure otherwise it would be easy.

We have custom watch scripts at work and I'm trying to sell them on Grunt but will need this feature to do it.

回答1:

You can use something like the following Gruntfile. Whenever a CoffeeScript file changes, it updates the configuration for coffee:dynamic_mappings to only use the modified file as the src.

This example is a slightly modified version of the example in the grunt-contrib-watch readme.

Hope it helps!

var path = require("path");
var srcDir = 'assets/scripts/src/';
var destDir = 'assets/scripts/dest/';

module.exports = function( grunt ) {
    grunt.initConfig( {
        coffee: {
            dynamic_mappings: {
                files: [{
                    expand: true,
                    cwd: srcDir,
                    src: '**/*.coffee',
                    dest: destDir,
                    ext: '.js'
                }]
            }
        },
        watch : {
            coffeescript : {
                files: 'assets/scripts/src/**/*.coffee',
                tasks: "coffee:dynamic_mappings",
                options: {
                    spawn: false, //important so that the task runs in the same context
                }
            }
        }
    } );

    grunt.event.on('watch', function(action, filepath, target) {
        var coffeeConfig = grunt.config( "coffee" );
        // Update the files.src to be the path to the modified file (relative to srcDir).
        coffeeConfig.dynamic_mappings.files[0].src = path.relative(srcDir, filepath);
        grunt.config("coffee", coffeeConfig);
    } );

    grunt.loadNpmTasks("grunt-contrib-coffee");
    grunt.loadNpmTasks("grunt-contrib-watch");

    grunt.registerTask("default", [ "coffee:dynamic_mappings", "watch:coffeescript"]);
};


回答2:

found a solution from an answer to a similar question https://stackoverflow.com/a/19722900/1351350

short answer: try https://github.com/tschaub/grunt-newer