2013-07-29 8 views
5

Ich schreibe ein node.js-Programm, das ein Verzeichnis mit einer großen (300-ish) Anzahl von scss-Projekten sehen wird. Grunt-watch (läuft entweder durch das Knotenmodul oder eigenständig, was auch immer funktioniert) wird so konfiguriert, dass bei jeder Änderung einer scss-Datei diese mit einem Kompaß kompiliert wird, die Ausgabedatei in ein separates Verzeichnis verschoben wird, zum Beispiel:Wie ändert man grunt watch Aufgaben basierend auf der Datei geändert?

./1234/style.scss geändert wurde >> Grunzen-Uhr läuft Grunzen-Kompass >> /foo/bar/baz/1234/style.css

aktualisiert

das Projekt-Verzeichnis, das die Datei in war offensichtlich ist sehr wichtig (wenn grunt-kompass alle kompilierten Dateien in dasselbe Verzeichnis geschickt hätte, wären sie durcheinander und unbrauchbar und die grunt-Automatisierung wäre sinnlos). Um sicherzustellen, dass alle Dateien an den richtigen Ort geroutet werden, ändere ich die Einstellungen von grunt-compass jedes Mal, wenn eine CSS-Datei aktualisiert wird.

Probe gruntfile:

module.exports = function(grunt) { 

grunt.initConfig({ 
    pkg: grunt.file.readJSON('package.json'), 
    watch: { 
     files: './*/*.scss', 
     tasks: ['compass'] 
    }, 
    compass: { 
     origin:{ 
     options: { 
      //temportary settings to be changed later 
      sassDir: './', 
      cssDir: './bar', 
      specify: './foo.scss' 
     } 
     } 
    } 
    }); 

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

    grunt.event.on('watch', function(action, filepath, target) { 
    var path = require('path'); 
    grunt.log.writeln(target + ': ' + filepath + ' might have ' + action); 
    var siteDirectory = path.dirname(filepath); 

    //changes sass directory to that of the changed file 
    var option = 'compass.origin.options.sassDir'; 
    var result = __dirname + '/' + siteDirectory; 
    grunt.log.writeln(option + ' changed to ' + result); 
    grunt.config(option, result); 

    //customizes css output directory so that file goes to correct place 
    option = 'compass.origin.options.cssDir'; 
    result = path.resolve(__dirname, '../', siteDirectory); 
    grunt.log.writeln(option + ' changed to ' + result); 
    grunt.config(option, result); 

    //grunt.task.run(['compass']); 

    }); 

}; 

Allerdings funktioniert dies nicht. Wenn Sie 'grunt watch' im ausführlichen Modus ausführen, sehen Sie, dass grunt sowohl die Funktion grunt.event.on als auch die Überwachungsaufgabe in separaten Prozessen ausführt. Das zweite Parsing der gruntfile setzt alle meine event.on-Konfigurationsänderungen auf die obigen Standardwerte zurück, und der Kompass kann nicht ausgeführt werden.

Wie in den event.on-Kommentaren zu sehen, habe ich versucht, eine grunt.task.run() hinzuzufügen, um sicherzustellen, dass Kompass im selben Prozess wie die event.on-Funktion ausgeführt wurde, die meine Konfigurationsänderungen beibehalten würde. Die Aufgabe wurde jedoch abgelehnt, wahrscheinlich weil I'm doing it wrong.

Leider werden die grunt.event.on-Variablen nicht an die definierte grunt-watch-Aufgabe gesendet, da ich sonst eine benutzerdefinierte Funktion schreiben könnte, die die Kompasseinstellungen ändert und dann den Kompass im selben Prozess ausführt.

Ich habe versucht, dies ohne Grunt zu implementieren, mit der in Kompass integrierten Uhrfunktion, aber Kompass kann nur einen statischen Ausgabepfad pro Projekt speichern und kann nur ein Projekt auf einmal ansehen.

Ich habe derzeit um dieses Problem, indem Sie ein Knotenprogramm, das den Standortnamen als Parameter übernimmt, umschreibt die grunfile.js durch Ausführen mit fs, und dann läuft "Grunt Watch" über eine Exec-Funktion. Dies hat jedoch seine eigenen Nachteile (ich kann die grunt.log-Daten nicht sehen) und ist schrecklich gewunden, also würde ich es gerne ändern.

Vielen Dank für einen Einblick.

+0

Dies beantwortet Ihre Frage nicht, aber warum gibt es eine Grunt-Contrib-Uhr für den Kompass? Compass ist bereits mit 'compass watch' ausgestattet – pllee

+0

Sie müssen' options: {nospawn: true} 'in Ihrer Watch-Task-Konfiguration angeben, damit die' watch' im selben Kontext läuft ([siehe diesen Abschnitt in Dokumentation]) (https://github.com/gruntjs/grunt-contrib-watch#compiling-files-as- needed)). –

+0

@ go-oleg Danke! Das funktioniert wunderbar. Ich bin überrascht, dass ich das in den Dokumenten nicht gesehen habe, da es direkt besagt, dass 'nospawn' Probleme wie meine löst. – anachronism

Antwort

11

Sie benötigen

options : { nospawn : true }

in Ihrer Uhr Aufgabe config angeben, die Uhr läuft im gleichen Kontext zu haben:

watch: { 
    files: './*/*.scss', 
    tasks: ['compass'], 
    options : { nospawn : true } 
} 

this section der Dokumentation für weitere Informationen zu diesem Thema finden.

+0

Würdigung dieser Antwort. Hatte die Dokumentation gelesen, war aber nicht klar über die Bedeutung von "Kontext" und darüber, wie sie von der Option "Nospawn" betroffen war. Vielen Dank! – jerome

+0

Vielen Dank für die Antwort! – vgrinko

+2

Um diese Antwort ab Juni 2016 zu aktualisieren, lautet die Option nun: 'spawn: false' – BigHeadCreations