Grunt: Как вообще запустить задачу less для нескольких файлов, которые обнаруживает задача просмотра?

Как я могу настроить свой сценарий grunt для запуска задачи less для нескольких файлов, которые обнаруживает задача просмотра? Можно ли это сделать без использования хака "grunt.event.on('watch'..."?

Это решение работает с одним файлом, но при одновременном сохранении двух файлов (в 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']);
};

Вся помощь приветствуется! Спасибо!


person henrikh    schedule 23.04.2015    source источник


Ответы (1)


После некоторых исследований и помощи на форуме grunt-contrib-watch мне удалось найти ответ на свой вопрос.

Во-первых, это невозможно без хака "grunt.event.on('watch'...").

Способ реализации одновременного сохранения нескольких файлов можно найти здесь, и его легко реализовать: 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']);
};
person henrikh    schedule 12.05.2015