2013-07-29 6 views
5

Piszę program node.js, który obejrzy katalog wypełniony dużą (300-ish) ilością projektów scss. Grunt-watch (uruchamiany albo przez moduł węzła, albo samodzielnie, bez względu na pracę) zostanie skonfigurowany tak, aby po zmianie pliku scss został skompilowany z kompasem, plik wyjściowy został przeniesiony do oddzielnego katalogu, na przykład:Jak zmodyfikować zadania związane z obserwacją gruntu w oparciu o zmieniony plik?

./1234/style.scss zmieniono >> grunt-watch biegnie grunt-kompas >> /foo/bar/baz/1234/style.css aktualizowane

katalogu projektu, że plik był to oczywiście bardzo ważne (gdyby chór-kompas przesłał wszystkie skompilowane pliki do tego samego katalogu, byłyby pomieszane i bezużyteczne, a automatyzacja chrząstek byłaby bezcelowa). Aby upewnić się, że wszystkie pliki są kierowane do właściwego miejsca, dynamicznie zmieniam ustawienia pomruków przy każdym uaktualnieniu pliku css.

Próbka 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']); 

    }); 

}; 

Jednak to nie działa. Jeśli uruchomisz "gruntowy zegarek" w trybie szczegółowym, zobaczysz, że funkcja ta uruchamia zarówno funkcję grunt.event.on, jak i zadanie watch w oddzielnych procesach. Drugie parsowanie pliku chropowatości powoduje, że cała moja konfiguracja event.on zmienia się na wartości domyślne, a kompas nie działa.

Jak widać w komentarzach do event.on, próbowałem dodać grunt.task.run(), aby upewnić się, że kompas został uruchomiony w tym samym procesie, co funkcja event.on, co zachowałoby moje zmiany w konfiguracji. Jednak zadanie odmówiło uruchomienia, prawdopodobnie dlatego, że I'm doing it wrong.

Niestety, zmienne grunt.event.on nie są wysyłane do zdefiniowanego zadania z pomiarem-obserwowaniem, w przeciwnym razie mógłbym napisać niestandardową funkcję, która zmieniłaby ustawienia kompasu, a następnie uruchomić kompas w tym samym procesie.

Próbowałem wykonać to bez chrzęstu, używając funkcji zegarka wbudowanej w kompas, jednak kompas może przechowywać tylko jedną statyczną ścieżkę wyjściową na projekt i może oglądać tylko jeden projekt naraz.

Obecnie obejść ten problem, dodając program węzła, który pobiera nazwę strony jako parametr, przepisuje plik grunfile.js, uruchamiając przy użyciu polecenia fs, a następnie uruchamiając "zegarek gruntowy" za pomocą funkcji exec. Ma to jednak swoje wady (nie mogę wyświetlić danych grunt.log) i jest okropnie zawiłe, więc chciałbym to zmienić.

Dziękuję bardzo za wszelki wgląd.

+0

To nie odpowiada na twoje pytanie, ale dlaczego jest tam contert-watch dla kompasu? Kompas ma już "zegarek kompasu" – pllee

+0

Musisz podać 'options: {nospawn: true}' w konfiguracji zadania zegarka, aby uruchomić 'watch' w tym samym kontekście ([zobacz tę sekcję w dokumentach] (https://github.com/gruntjs/grunt-contrib-watch#compiling-files-as-needed)). –

+0

@ go-oleg Dziękuję! Działa to cudownie. Jestem zaskoczony, że nie widziałem tego w dokumentach, ponieważ bezpośrednio stwierdza, że ​​'nospawn' rozwiązuje problemy takie jak moje. – anachronism

Odpowiedz

11

musisz określić

options : { nospawn : true }

w zegarku zadań config mieć przebieg obejrzenia w tym samym kontekście:

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

Zobacz this section dokumentacji, aby uzyskać więcej informacji na ten temat.

+0

Doceniłem tę odpowiedź. Czytałem dokumentację, ale nie było jasne, co to znaczy "kontekst" i jak wpłynęła na niego opcja "nospawn". Dzięki! – jerome

+0

Dziękuję za odpowiedź! – vgrinko

+2

Aby dodać aktualizację do tej odpowiedzi, od czerwca 2016 opcja jest teraz: 'spawn: false' – BigHeadCreations

Powiązane problemy