How can I use grunt-regarde with grunt-contrib-coffee to only compile changed .coffee files?

前端 未结 3 819
长发绾君心
长发绾君心 2020-12-29 10:57

My project has over 300 CoffeeScript files, so it takes several seconds to recompile everything. I\'d like to only recompile the changed CoffeeScript files.

Here\'s

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-29 11:52

    I've had the same issue. I solved it using the regarde:file event.

    First I listen for changed files by using the regarde:file event. This will feed the configuration for two tasks: clean:coffee if files in the source location has been deleted and coffee:refresh if files have been changed/added.

    Then the regarde task will trigger its tasks, which will launch refresh:coffee (not to be mistaken from coffee:refresh). This task will check if there is configuration added for clean:coffee and/or for coffee:refresh and run these tasks if needed (via function grunt.task.run). If will also reset the flag, which will cause the next received regarde:file event to cleanup the configuration again.

    In depth explanation:

    First of all, regarde config:

     // watch for changed coffeescript files
     coffee: {
        files: 'path/to/coffee/**/*.coffee',
        tasks: ['refresh:coffee', 'livereload']
     },
    

    Then I listen for the regarde:file event, where I update the clean:coffee and coffee:refresh file lists in their config.

    Feed the configuration based on the regarde:file event:

    grunt.event.on('regarde:file', function (status, target, filepath) {
       if (resetFlag) {
          // clean file list from previous cycle, so clean clean:coffee and coffee:refresh
          // file lists
          ...
    
          resetFlag = false;
       } 
       if (status === 'deleted') {
            if (filepath) {
                // calculate filepath's destination and  
                // add it to clean:coffee filelist
            }
        } else {
            if (!grunt.file.isDir(filepath)) {
                // add filepath to coffee:refresh filelist
            }
        }
    }
    

    It is easy to update configuration via grunt.config() function. Below the code snippets to feed coffee:refresh and clean:coffee.

    Adding config to coffee:refresh:

    var config = grunt.config('coffee') || {};
    var value = config.refresh || {};
    value.files = value.files || [];
    ...
    var cwd = path.dirname(filepath),
        src = path.basename(filepath),
        dest = cwd.replace('path/to/source', 'path/to/dest');
        value.files.push({
           expand:true,
           src:src,
           dest:dest,
           cwd:cwd,
           ext:'.js'
        });
    grunt.config('coffee', config);
    

    Adding config to clean:coffee:

        var cwd = path.dirname(filepath),
            src = path.basename(filepath),
            dest = cwd.replace('path/to/source', 'path/to/dest');
            value.src.push(path.join(dest, src.replace('coffee', 'js')));
        // clean only what has been removed
            config = grunt.config('clean') || {};
    
        config.coffee = value;
    
        grunt.config('clean', config);
    

    Task refresh:coffee gets triggered:

        grunt.registerMultiTask('refresh', 'refreshing the changed file(s)', function () {
            this.requires('regarde');
    
            var tasks = [];
            var clean = grunt.config('clean');
    
            // check if there is clean:refresh config available
            if (clean && clean[this.target]) {
                tasks.push('clean:' + this.target);
            }
            var config = grunt.config(this.target);
    
            // check if there is coffee:refresh config available
            if (config && config.refresh) {
                tasks.push(this.target + ':refresh');
            }
            // run the tasks
            grunt.task.run(tasks);
    
            // set the resetFlag back to true
            resetFlag = true;
        });
    

提交回复
热议问题