Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grunt watch: compile only one file not all

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.

like image 273
James Billings Avatar asked Sep 19 '13 16:09

James Billings


2 Answers

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"]);
};
like image 56
go-oleg Avatar answered Nov 20 '22 13:11

go-oleg


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

like image 31
codeboy Avatar answered Nov 20 '22 15:11

codeboy