2013-02-25 56 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默認不生成子進程。

相關問題