Grunt:如何在监视任务检测到的多个文件上一般运行较少的任务?

时间:2015-04-23 08:02:01

标签: generics gruntjs grunt-contrib-watch grunt-contrib-less

如何设置我的grunt脚本,以便在监视任务检测到的多个文件上运行较少的任务? 是否可以在不使用“grunt.event.on('watch'...”hack?

的情况下执行此操作

此解决方案适用于一个文件,但是当同时保存两个文件时(在Visual Studio中),只生成一个css。

剧本:

'useStrict';
module.exports = function (grunt) {
    grunt.initConfig({
        globalConfig: globalConfig,
        less: {
            all: {
                options: {
                    compress: false,
                },
                files: '',
            },
        },
        watch: {
            all: {
                files: [
                        'Main/**/*.less',                       
                ],
                tasks: ['less'],
                options: {
                    nospawn: true
                }
            }
        }       
    });

    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.event.on('watch', function(action, filepath) {

        // Handling .less imports so that when the watch task
        // detects change in an imported file, "the main .less file
        // that does the import" is compiled, instead of the imported file.
        // Naming convention for imported files: Title of main file that 
        // imports + "-" + name describing the imported file
        // E.g. Main.less, Main-Colors.less, Main-Structure.less, Main-Utility.less

        var splittedPath = filepath.split('/');
        var filename = splittedPath[splittedPath.length - 1];
        delete splittedPath[splittedPath.length - 1];
        var fileDirectoryPath = splittedPath.join('/');
        var splittedFilename = filename.split('-');
        if (splittedFilename.length > 1){
            filepath = fileDirectoryPath + splittedFilename[0] + '.less';
        }

        grunt.config(['less', 'all', 'files'], [{
            expand: true,
            src: filepath,
            ext: '.css',
        }]);
    });

    grunt.registerTask('default', ['watch']);
};

所有帮助表示赞赏!谢谢!

1 个答案:

答案 0 :(得分:1)

经过对grunt-contrib-watch论坛的一些研究和帮助后,我设法找到了我的问题的答案。

首先,没有" grunt.event.on('观看' ..." hack。

,这是不可能的。

此处可以找到实现多个文件同时保存的方法,并且易于实现:https://github.com/gruntjs/grunt-contrib-watch#compiling-files-as-needed

我更新的代码解决了这个问题的结果:

'useStrict';
module.exports = function (grunt) {
    grunt.initConfig({
        globalConfig: globalConfig,
        less: {
            all: {
                files: 'event will load filepaths on the fly',
                options: {
                    compress: false,
                }
            },
        },
        watch: {
            all: {
                files: ['Main/**/*.less'],
                tasks: ['less'],
                options: {
                    nospawn: true
                }
            }
        }       
    });

    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');

    var changedFiles = Object.create(null);
    var onChange = grunt.util._.debounce(function() {
        grunt.config(['less', 'all', 'files'], [{
            expand: true,
            src: Object.keys(changedFiles),
            ext: '.css',
        }]);
        changedFiles = Object.create(null);
    }, 200);

    grunt.event.on('watch', function(action, filepath) {
        // Handling .less imports so that when the watch task
        // detects change in an imported file the main .less file
        // that imports is compiled instead of the imported file.
        // Naming convention for imported files:
        // title of main file that imports + "-" + name describing the imported file
        var splittedPath = filepath.split('/');
        var filename = splittedPath[splittedPath.length - 1];
        delete splittedPath[splittedPath.length - 1];
        var fileDirectoryPath = splittedPath.join('/');
        var splittedFilename = filename.split('-');
        if (splittedFilename.length > 1){
            filepath = fileDirectoryPath + splittedFilename[0] + '.less';
        }

        changedFiles[filepath] = action;
        onChange();
    });

    grunt.registerTask('default', ['watch']);
};