G运行t:如何在 watch 任务检测到的多个文件上一般地 运行 less 任务?

Grunt: How to generically run less task on multiple files that the watch task detects?

如何将我的 g运行t 脚本设置为 运行 对监视任务检测到的多个文件执行更少的任务? 是否可以在不使用 "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']);
};

感谢所有帮助!谢谢!

在 grunt-contrib-watch 论坛上进行了一些研究和帮助后,我设法找到了问题的答案。

首先,如果没有 "grunt.event.on('watch'..." 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']);
};