2013-02-25 13 views
11

Mein Projekt enthält über 300 CoffeeScript-Dateien. Es dauert also einige Sekunden, um alles neu zu kompilieren. Ich möchte nur die geänderten CoffeeScript-Dateien neu kompilieren.Wie kann ich grunt-regarde mit grunt-contrib-coffee verwenden, um nur geänderte .coffee-Dateien zu kompilieren?

Hier kommt ich am ehesten soweit, aber die Ordnerstruktur "frontend-src/coffeescript" wird aus dem Verzeichnis src in das Verzeichnis dest kopiert.

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'] 
    } 
} 

Dies ist alles mit Grunt 0.4.0. Jede Hilfe würde sehr geschätzt werden!

Antwort

2

Ich hatte das gleiche Problem. Ich löste es mit dem regarde:file Ereignis.

Zuerst höre ich nach geänderten Dateien mit dem regarde:file Ereignis. Dadurch wird die Konfiguration für zwei Aufgaben bereitgestellt: clean:coffee, wenn Dateien am Quellspeicherort gelöscht wurden, und coffee:refresh, wenn Dateien geändert/hinzugefügt wurden.

Dann löst die Task regarde ihre Aufgaben aus, die refresh:coffee starten (nicht zu verwechseln mit coffee:refresh). Diese Aufgabe prüft, ob für clean:coffee und/oder für coffee:refresh eine Konfiguration hinzugefügt wurde, und führt diese Aufgaben bei Bedarf aus (über die Funktion grunt.task.run). Wenn das Flag zurückgesetzt wird, wird das nächste empfangene Ereignis regarde:file die Konfiguration erneut bereinigen.

Vertiefen Erklärung:

Zunächst einmal regarde config:

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

Dann höre ich die regarde:file Veranstaltung, wo ich die clean:coffee und coffee:refresh Dateilisten in ihrer Konfiguration aktualisieren.

-Feed der Konfiguration auf der Grundlage der regarde:file Veranstaltung:

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 
     } 
    } 
} 

Es ist eine einfache Konfiguration über grunt.config() Funktion zu aktualisieren. Unter den Code-Schnipsel zu Feed coffee:refresh und clean:coffee.

Config Hinzufügen zu 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 Hinzufügen:

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); 

Aufgabe refresh:coffee wird ausgelöst:

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 ist ein Array korrekt?

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

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

ich durch Grunzen-contrib-Kaffees Quelle sah für eine Sekunde, um zu sehen, ob es der Handhabung nicht richtig sein könnte, was auch immer Sie es sind zu geben. Sah irgendwie wahrscheinlich aus, dass das Array, in dem du es gibst, nicht gefangen und bearbeitet wird.

denke ich, was Sie vorbei versehentlich sein: src: [ '[path1, path2, path3, etc]' ]

Wenn ich weg Basis, lassen Sie einen Kommentar und ich werde diese Antwort löschen.

+1

'src: '<% = grunt.regarde.changed%>' 'funktionierte für mich (musste in eine Zeichenfolge eingeschlossen werden). – Adam

+0

Danke, ich habe es oben geändert. – nackjicholson

3

Ich hatte dieses Problem selbst, und ich konnte mit einer Lösung kommen für sie durch die Kommentare zu diesem Thema inspiriert: https://github.com/gruntjs/grunt-contrib-watch/issues/14

Es ist eigentlich für die Grunzen-contrib-Uhr-Plugin, aber es sollte arbeiten auch für grunt-regarde, da es ähnliche Ereignisse gibt.

Die Idee ist, einen Callback das watch Ereignis zu binden, in dem Sie eine neue Aufgabe der grunt-Konfiguration mit dem Pfad der geänderten Datei hinzufügen, und führen Sie es dann aus.

Aus meiner 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') 

Die nospawn für die Uhren Aufgabe wichtig ist, so läuft er die neue Aufgabe vor der livereload Aufgabe. Ich bin mir ziemlich sicher, dass regarde standardmäßig keine Child-Prozesse erzeugt.

Verwandte Themen