Gruntjs Grunt仅在更改的文件上减少监视

Gruntjs Grunt仅在更改的文件上减少监视,gruntjs,grunt-contrib-watch,Gruntjs,Grunt Contrib Watch,我想要一个包含两个任务的gruntfile:less(编译所有less文件)和watch(侦听更改并重新编译更改的文件) 我有以下Gruntfile.js: module.exports = function(grunt) { var files = [ { expand: true, cwd: 'media/less', src: ['*.less'], dest: 'med

我想要一个包含两个任务的gruntfile:less(编译所有less文件)和watch(侦听更改并重新编译更改的文件)

我有以下Gruntfile.js:

module.exports = function(grunt) {
    var files = [
        {
            expand: true,
            cwd: 'media/less',
            src: ['*.less'],
            dest: 'media/css/',
            ext: '.css'
        },
        {
            expand: true,
            cwd: 'media/less/vendor',
            src: ['*.less'],
            dest: 'media/css/vendor/',
            ext: '.css'
        },
        {
            expand: true,
            cwd: 'media/admin/less',
            src: ['*.less'],
            dest: 'media/admin/css/',
            ext: '.css'
        }
    ];

    grunt.initConfig({
        less: {
            development: {
                options: {
                    compress: false,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            },
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            }
        },
        watch: {
            styles: {
                files: ['media/**/*.less'],
                tasks: ['less:development'],
                options: {
                    nospawn: true
                }
            }
        }
    });

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

    grunt.registerTask('default', ['less:development']);
};
less
任务正常运行,没有任何问题。然而,
watch
任务监听更改,但在更改文件时重新编译所有文件。我怀疑这与我如何设置
less
任务有关,因为我希望less文件列表是动态的,而不是手动添加每个文件


根据grunt的说法,它应该已经支持了这一点,但我不确定如何支持。

我不确定你的问题的当前标题是什么意思grunt只在已更改的文件中查看较少的内容。你是说这是个问题吗?这是
watch
任务的预期行为,它将监视指定的文件以进行更改,并运行您指定的任务—在本例中是
LESS
编译

我对你的文件做了一些更改。其中一些被简化了,一些被修改了,以保持脚本的灵活性和可扩展性

首先,通过运行以下命令将
下划线
作为依赖项安装:

npm install underscore --save-dev
然后对
grunfile.js执行以下更改:

module.exports = function(grunt) {

    var _ = require('underscore');

    var files = {
        app : {
            '<%= path.styles.css %>/styles.css' : '<%= path.styles.less %>/*.less'
        },
        vendor : {
            '<%= path.styles.css %>/styles-vendor.css' : '<%= path.styles.vendor %>/*.less'
        },
        admin : {
            '<%= path.styles.css %>/styles-admin.css' : '<%= path.styles.admin %>/*.less'
        }
    }

    function all() {
        'use strict';
        var allfiles = {},
            i = {};

        for (i in files) {
            _.extend(allfiles, files[i]);
        }
        return allfiles;
    }

    grunt.initConfig({
        path : {
            media : 'media',
            styles : {
                css: 'media/css',
                less: 'media/less',
                admin: 'media/admin/less',
                vendor: '<%= path.styles.less %>/vendor'                
            }
        },
        less: {
            development: {
                options: {
                    compress: false,
                    yuicompress: true,
                    optimization: 2
                },
                files: (all())
            },
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2
                },
                files: (all())
            }
        },
        watch: {
            styles: {
                files: ['<%= path.media %>/**/*.less'],
                tasks: ['less:development'],
                options: {
                    nospawn: true
                }
            }
        }
    });

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

    // run several tasks as default (handy for complex projects)
    grunt.registerTask('dist', [ // run with 'grunt dist'
        'less:production'
    ]);
    grunt.registerTask('dev', [ // default, will run with 'grunt' only
        'less:development'
    ]);

    grunt.registerTask('default', 'dev');
};
然后,您可以运行以下任一项:

grunt watch:app
grunt watch:vendor
grunt watch:admin
您始终可以选择直接运行任务,一次:

grunt less:app
grunt less:vendor
grunt less:admin

希望这有帮助!请注意,我还没有对此进行测试。

最终使用了
watch
事件并覆盖
less
任务的
files
属性。这是我的最终代码:

module.exports = function(grunt) {
    var files = [
        {
            expand: true,
            cwd: 'media/less',
            src: ['*.less'],
            dest: 'media/css/',
            ext: '.css',
            extDot: 'last'
        },
        {
            expand: true,
            cwd: 'media/less/vendor',
            src: ['*.less'],
            dest: 'media/css/vendor/',
            ext: '.css',
            extDot: 'last'
        },
        {
            expand: true,
            cwd: 'media/admin/less',
            src: ['*.less'],
            dest: 'media/admin/css/',
            ext: '.css',
            extDot: 'last'
        }
    ];

    grunt.initConfig({
        less: {
            development: {
                options: {
                    compress: false,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            },
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            }
        },
        watch: {
            styles: {
                files: ['media/**/*.less'],
                tasks: ['less:development'],
                options: {
                    nospawn: true
                }
            }
        }
    });

    grunt.event.on('watch', function(action, filepath){
        // ignore include files, TODO: have naming convention
        // if an include file has been changed, all files will be re-compiled
        if(filepath.indexOf('.inc.') > -1)
            return true;

        // might not be the most efficient way to do this
        var srcDir = filepath.split('/');
        var filename = srcDir[srcDir.length - 1];
        delete srcDir[srcDir.length - 1];
        srcDir = srcDir.join('/');
        var destDir = srcDir.replace(/less/g, 'css');

        grunt.config('less.development.files', [{
            src: filename,
            dest: destDir,
            expand: true,
            cwd: srcDir,
            ext: '.css',
            extDot: 'last'
        }]);
    });

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

    grunt.registerTask('default', ['less:development']);
};

不是我想要的,虽然不远。所以需要的流程是:我更改一个文件,这一个文件被编译。当前流程:我更改一个文件,所有文件都重新编译。使用您的解决方案(第二个),运行
less:development
任务和
less:app
任务。另外,我也不想将较少的文件捆绑到一个CSS文件中,我想保持文件结构不变。我复制了您的设置,无法解决此难题。您提到的问题指出了在不同的项目中提出的两个问题,它们试图处理相同的问题]和],但还没有100%解决。在这一点上,我认为
LESS
任务是基于文件夹的,就像
Compass
任务一样(对于
SASS
)。在
Compass
的例子中,他们甚至明确地提到了它。设法解决了它。花了大约3个小时,但希望它现在能正常工作。看看我的答案,看看我做了什么。
module.exports = function(grunt) {
    var files = [
        {
            expand: true,
            cwd: 'media/less',
            src: ['*.less'],
            dest: 'media/css/',
            ext: '.css',
            extDot: 'last'
        },
        {
            expand: true,
            cwd: 'media/less/vendor',
            src: ['*.less'],
            dest: 'media/css/vendor/',
            ext: '.css',
            extDot: 'last'
        },
        {
            expand: true,
            cwd: 'media/admin/less',
            src: ['*.less'],
            dest: 'media/admin/css/',
            ext: '.css',
            extDot: 'last'
        }
    ];

    grunt.initConfig({
        less: {
            development: {
                options: {
                    compress: false,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            },
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2
                },
                files: files
            }
        },
        watch: {
            styles: {
                files: ['media/**/*.less'],
                tasks: ['less:development'],
                options: {
                    nospawn: true
                }
            }
        }
    });

    grunt.event.on('watch', function(action, filepath){
        // ignore include files, TODO: have naming convention
        // if an include file has been changed, all files will be re-compiled
        if(filepath.indexOf('.inc.') > -1)
            return true;

        // might not be the most efficient way to do this
        var srcDir = filepath.split('/');
        var filename = srcDir[srcDir.length - 1];
        delete srcDir[srcDir.length - 1];
        srcDir = srcDir.join('/');
        var destDir = srcDir.replace(/less/g, 'css');

        grunt.config('less.development.files', [{
            src: filename,
            dest: destDir,
            expand: true,
            cwd: srcDir,
            ext: '.css',
            extDot: 'last'
        }]);
    });

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

    grunt.registerTask('default', ['less:development']);
};