2013-02-25 55 views
11

我的项目拥有300多个CoffeeScript文件,因此需要几秒钟才能重新编译所有内容。我只想重新编译已更改的CoffeeScript文件。如何将grunt-regarde与grunt-contrib-coffee一起使用,以仅编译已更改的.coffee文件?

这里是我到目前为止最接近的,但是“frontend-sr​​c/coffeescript”文件夹结构正在从src目录复制到dest目录。

coffee: { 
    changed: { 
    expand: true, 
    cwd: './', 
    src: ['<%= grunt.regarde.changed %>'], 
    dest: 'public/js/', 
    ext: '.js' 
    } 
}, 
regarde: { 
    coffee: { 
    files: 'frontend-src/coffeescript/**/*.coffee', 
    tasks: ['coffee:changed', 'livereload'] 
    } 
} 

这都是用Grunt 0.4.0。任何帮助将不胜感激!

回答

2

我有同样的问题。我使用regarde:file事件解决了它。

首先我使用regarde:file事件来侦听已更改的文件。这将为两个任务提供配置:clean:coffee如果源位置中的文件已被删除,并且coffee:refresh如果文件已被更改/添加。

然后regarde任务将触发其任务,这将启动refresh:coffee(不要误从coffee:refresh)。此任务将检查是否为clean:coffee和/或coffee:refresh添加了配置,并在需要时运行这些任务(通过功能grunt.task.run)。如果还将重置该标志,这将导致下一个接收到的事件再次清除配置。

深入的解释:

首先,regarde配置:

// watch for changed coffeescript files 
coffee: { 
    files: 'path/to/coffee/**/*.coffee', 
    tasks: ['refresh:coffee', 'livereload'] 
}, 

然后我听为regarde:file活动期间,凡在我自己的配置更新clean:coffeecoffee:refresh文件列表。

饲料基础上,regarde:file事件配置:

grunt.event.on('regarde:file', function (status, target, filepath) { 
    if (resetFlag) { 
     // clean file list from previous cycle, so clean clean:coffee and coffee:refresh 
     // file lists 
     ... 

     resetFlag = false; 
    } 
    if (status === 'deleted') { 
     if (filepath) { 
      // calculate filepath's destination and 
      // add it to clean:coffee filelist 
     } 
    } else { 
     if (!grunt.file.isDir(filepath)) { 
      // add filepath to coffee:refresh filelist 
     } 
    } 
} 

这是很容易通过grunt.config()功能更新配置。在代码片段的下方提供coffee:refreshclean:coffee

添加config来coffee:refresh

var config = grunt.config('coffee') || {}; 
var value = config.refresh || {}; 
value.files = value.files || []; 
... 
var cwd = path.dirname(filepath), 
    src = path.basename(filepath), 
    dest = cwd.replace('path/to/source', 'path/to/dest'); 
    value.files.push({ 
     expand:true, 
     src:src, 
     dest:dest, 
     cwd:cwd, 
     ext:'.js' 
    }); 
grunt.config('coffee', config); 

添加config来clean:coffee

var cwd = path.dirname(filepath), 
     src = path.basename(filepath), 
     dest = cwd.replace('path/to/source', 'path/to/dest'); 
     value.src.push(path.join(dest, src.replace('coffee', 'js'))); 
    // clean only what has been removed 
     config = grunt.config('clean') || {}; 

    config.coffee = value; 

    grunt.config('clean', config); 

任务refresh:coffee被触发:

grunt.registerMultiTask('refresh', 'refreshing the changed file(s)', function() { 
     this.requires('regarde'); 

     var tasks = []; 
     var clean = grunt.config('clean'); 

     // check if there is clean:refresh config available 
     if (clean && clean[this.target]) { 
      tasks.push('clean:' + this.target); 
     } 
     var config = grunt.config(this.target); 

     // check if there is coffee:refresh config available 
     if (config && config.refresh) { 
      tasks.push(this.target + ':refresh'); 
     } 
     // run the tasks 
     grunt.task.run(tasks); 

     // set the resetFlag back to true 
     resetFlag = true; 
    }); 
0

grunt.regarde.changed是一个数组是否正确?

应该src: ['<%= grunt.regarde.changed %>']

src: '<%= grunt.regarde.changed %>'

我通过咕噜-的contrib咖啡对第二来源看,看它是否可能是不正确处理无论你给它。看起来有可能是你给它的串化数组,不会被捕获和处理。

我认为你不小心路过什么可能是:src: [ '[path1, path2, path3, etc]' ]

如果我大错特错,发表评论,我会删除这个答案。

+1

'src:'<%= grunt.regarde.changed%>''为我工作(需要用字符串包装)。 – Adam 2013-04-29 23:38:07

+0

谢谢,我改变了上面。 – nackjicholson 2013-04-30 06:22:57

3

我有这个问题我自己,我能拿出一个解决方案,它通过对这个问题的意见的启发: https://github.com/gruntjs/grunt-contrib-watch/issues/14

它实际上是繁重的-的contrib手表的插件,但它应该也为grunt-regarde工作,因为它有类似的事件。

这个想法是绑定一个回调watch事件,在这个事件中,你可以用grunt配置文件的路径添加一个新的任务,然后运行它。

从我Gruntfile.coffee

coffee: 
    app: 
     expand: true 
     cwd: 'app/' 
     src: ['*.coffee',"**/*.coffee"] 
     dest: './public/temp' 
     ext: '.js' 
watch: 
    coffee: 
     files: ['app/**/*.coffee'] 
     tasks: ['livereload'] 
     options: 
      nospawn: true 

grunt.event.on 'watch', (action, filepath) ->  
    cwd = 'app/' 
    filepath = filepath.replace(cwd,'') 
    grunt.config.set('coffee', 
     changed: 
      expand: true 
      cwd: cwd 
      src: filepath 
      dest: './public/temp' 
      ext: '.js' 
    ) 
    grunt.task.run('coffee:changed') 

的nospawn是手表任务重要,所以它运行的livereload任务之前,新的任务。我相当确定regarde默认不生成子进程。

相关问题