2014-04-01 53 views
2

我想要有一个gruntfile有2个任务:less(编译所有较少的文件)并观察(监听更改并重新编译更改后的文件)。Grunt只看更改文件

我有以下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任务有关,因为我希望我的较少文件列表是动态的,而不是手动添加每个文件。

根据this answer grunt应该已经支持这个,但我不确定如何。

回答

1

使用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']); 
}; 
0

我不确定你的意思与您的问题的当前标题咕噜在更改文件只看手表。你的意思是这是一个问题吗?这是watch任务的预期行为,它将监视为更改指定的文件并运行您指定的任务 - 在本例中为LESS编译。

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

首先安装underscore作为依赖,通过运行:

npm install underscore --save-dev 

然后执行以下更改Gruntfile.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'); 
}; 

如果你想要的是实际编译文件的套单独files.app,files.vendor & files.admin),您可能需要再分割一些任务,如下所示:

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

然后你可以再运行这些:

grunt watch:app 
grunt watch:vendor 
grunt watch:admin 

你总是可以选择直接运行的任务,一旦:

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

希望这有助于!请注意,我没有测试过这个。

+0

不是我真正想要的,虽然不远。所以期望的流程:我改变一个文件,一个文件被编译。当前流程:我更改一个文件,所有文件都会重新编译。通过您的解决方案(第二个),“less:development”任务和“less:app”任务都将运行。另外,我也不想将LESS文件捆绑到一个单独的CSS文件中,我希望保持文件结构相同。 –

+0

我已经复制了您的设置并无法解决难题。你提到的SO指出了在不同项目中提出的两个问题,它们试图解决同样的问题[[1](https://github.com/gruntjs/grunt-contrib-watch/issues/14)]和[[2 ](HTTPS:// github上。com/shama/gaze/issues/14)],但还没有100%解决。此时,我认为“LESS”任务是基于文件夹的,“Compass”任务(用于“SASS”)也是。在“Compass”的情况下,他们甚至在[自述文件]中明确提到它(https://github.com/gruntjs/grunt-contrib-compass)。 –

+0

管理解决它。花了大约3小时,但希望它现在能正常工作。看到我的答案,看看我做了什么。 –

相关问题