2015-09-01 5 views
14

Ich habe zwei Verzeichnisse src und compiled. Ich möchte eine unidirektionale Datensynchronisation von src bis compiled mit Grunt Watch sicherstellen. Als Zwischenschritt möchte ich *.less Dateien sowie eine Teilmenge von *.js Dateien kompilieren, die mit ES6-Syntax geschrieben sind.Tiefe, unidirektionale Synchronisation zweier Verzeichnisse mit grunt-contrib-watch. Code funktioniert, aber grunt-contrib-Uhr Re-Initiierungszeit ist zu langsam

Ich habe erfolgreich die Aufgaben geschrieben, das zu tun, was ich brauche:

// NOTE: Spawn must be disabled to keep watch running under same context in order to dynamically modify config file. 
watch: { 
    // Compile LESS files to 'compiled' directory. 
    less: { 
    options: { 
     interrupt: true, 
     spawn: false, 
     cwd: 'src/less' 
    }, 
    files: ['**/*.less'], 
    tasks: ['less'] 
    }, 
    // Copy all non-ES6/LESS files to 'compiled' directory. Include main files because they're not ES6. Exclude LESS because they're compiled. 
    copyUncompiled: { 
    options: { 
     event: ['added', 'changed'], 
     spawn: false, 
     cwd: 'src' 
    }, 
    files: ['**/*', '!**/background/**', '!**/common/**', '!contentScript/youTubePlayer/**/*', '!**/foreground/**', '!**/test/**', '!**/less/**', '**/main.js'], 
    tasks: ['copy:compileSingle'] 
    }, 
    // Compile and copy ES6 files to 'compiled' directory. Exclude main files because they're not ES6. 
    copyCompiled: { 
    options: { 
     event: ['added', 'changed'], 
     spawn: false, 
     cwd: 'src/js' 
    }, 
    files: ['background/**/*', 'common/**/*', 'contentScript/youTubePlayer/**/*', 'foreground/**/*', 'test/**/*', '!**/main.js'], 
    tasks: ['babel:compileSingle'] 
    }, 
    // Whenever a file is deleted from 'src' ensure it is also deleted from 'compiled' 
    remove: { 
    options: { 
     event: ['deleted'], 
     spawn: false, 
     cwd: 'src' 
    }, 
    files: ['**/*'], 
    tasks: ['clean:compiledFile'] 
    } 
} 

    grunt.event.on('watch', function(action, filepath, target) { 
    // Determine which task config to modify based on the event action. 
    var taskTarget = ''; 
    if (action === 'deleted') { 
     taskTarget = 'clean.compiledFile'; 
    } else if (action === 'changed' || action === 'added') { 
     if (target === 'copyCompiled') { 
     taskTarget = 'babel.compileSingle'; 
     } else if (target === 'copyUncompiled') { 
     taskTarget = 'copy.compileSingle'; 
     } 
    } 

    if (taskTarget === '') { 
     console.error('Unable to determine taskTarget for: ', action, filepath, target); 
    } else { 
     // Drop src off of filepath to properly rely on 'cwd' task configuration. 
     grunt.config(taskTarget + '.src', filepath.replace('src\\', '')); 
    } 
    }); 

Diese Aufgaben sehen die entsprechenden Dateien. Der Ereignishandler ändert die Aufgaben cleancopy und babel dynamisch so, dass sie an den Dateien arbeiten, die hinzugefügt/geändert/entfernt werden.

jedoch, Ich beobachte mehrere tausend Dateien und die Uhr Aufgabe, eine nicht-triviale Menge Zeit in Anspruch nimmt zu initialisieren. Auf meiner High-End-Entwicklung PC Initialisierung dauert 6+ Sekunden. Dieses Problem wird durch die Tatsache verstärkt, dass die Überwachungsaufgabe nach jeder Aufgabe neu initialisiert wird.

Das bedeutet, dass, wenn ich zwei Dateien, fileA und fileB, und ich fileA ändern und speichern Sie dann eine dort 6+ zweite Periode, wo Uhr Modifikationen fileB nicht erkennt. Dies führt zu einer Synchronisation zwischen meinen beiden Verzeichnissen.

ich diese GitHub Frage in Bezug auf meinem Problem gefunden, aber es ist noch offen und unbeantwortet: https://github.com/gruntjs/grunt-contrib-watch/issues/443

Die Diskussion über GitHub hebt hervor, dass das Problem kann auftreten, nur dann, wenn spawn: false eingestellt wurde, aber nach den Grunt Watch documentation:

Wenn Sie Ihre Konfiguration dynamisch ändern müssen, muss die Spawn-Option deaktiviert sein, damit die Uhr im selben Kontext läuft.

Als solcher glaube ich, dass ich spawn: false weiter verwenden muss.

Ich muss davon ausgehen, dies ist eine ziemlich Standard-Prozedur für Grunt-Aufgaben. Fehle ich etwas Offensichtliches hier? Ist die Watch-Aufgabe für diesen Zweck ungeeignet? Andere Optionen?

+0

Haben Sie sich [grunt-neuere] (https://www.npmjs.com/package/grunt-newer) angesehen? Klingt so, als ob * lowkay * genau das in der geöffneten Ausgabe erwähnt. – DavidDomain

+0

Spielte in den letzten ein oder zwei Stunden mit grun-neueren. Es funktioniert gut für kompilierten Code, aber wenn eine Datei von 'src' nach 'kompiliert' kopiert wird, ohne dass Änderungen erforderlich sind, wird die 'letzte Änderung' der Datei nicht aktualisiert. Dies führt dazu, dass die Datei bei jeder Ausführung der Aufgabe eingeschlossen wird. Wenn ich einen Weg finden kann, das zu beheben, dann wird grunt-newer ausreichen. –

+1

Verwenden Sie [jit-grunt] (https://github.com/shootouroo/jit-grunt)? Das würde bei der Beschleunigung der Uhraufgabe –

Antwort

4

In Ordnung, so habe ich eine funktionierende Lösung, aber es ist nicht hübsch.

Ich habe am Ende grunt-newer verwendet, um mit der Lösung zu helfen. Leider funktioniert es nicht gut mit grunt-contrib-copy, da das Kopieren einer Datei nicht ihre zuletzt geänderte Zeit aktualisiert und grunt-neuere dann 100% der Zeit ausführt.

Also, ich Grunzen-contrib-Kopie gegabelt und hat eine Option zu ermöglichen, den Zeitpunkt der letzten Änderung der Aktualisierung: https://github.com/MeoMix/grunt-contrib-copy

Damit bin ich nun in der Lage zu schreiben:

// NOTE: Spawn must be disabled to keep watch running under same context in order to dynamically modify config file. 
watch: { 
    // Compile LESS files to 'compiled' directory. 
    less: { 
    options: { 
     interrupt: true, 
     cwd: 'src/less' 
    }, 
    files: ['**/*.less'], 
    tasks: ['less'] 
    }, 
    // Copy all non-ES6/LESS files to 'compiled' directory. Include main files because they're not ES6. Exclude LESS because they're compiled. 
    copyUncompiled: { 
    options: { 
     event: ['added', 'changed'], 
     cwd: 'src' 
    }, 
    files: ['**/*', '!**/background/**', '!**/common/**', '!contentScript/youTubePlayer/**/*', '!**/foreground/**', '!**/test/**', '!**/less/**', '**/main.js'], 
    tasks: ['newer:copy:compiled'] 
    }, 
    // Compile and copy ES6 files to 'compiled' directory. Exclude main files because they're not ES6. 
    copyCompiled: { 
    options: { 
     event: ['added', 'changed'], 
     cwd: 'src/js' 
    }, 
    files: ['background/**/*', 'common/**/*', 'contentScript/youTubePlayer/**/*', 'foreground/**/*', 'test/**/*', '!**/main.js'], 
    tasks: ['newer:babel:compiled'] 
    }, 
    // Whenever a file is deleted from 'src' ensure it is also deleted from 'compiled' 
    remove: { 
    options: { 
     event: ['deleted'], 
     spawn: false, 
     cwd: 'src' 
    }, 
    files: ['**/*'], 
    tasks: ['clean:compiledFile'] 
    } 
} 

grunt.event.on('watch', function(action, filepath) { 
    if (action === 'deleted') { 
    // Drop src off of filepath to properly rely on 'cwd' task configuration. 
    grunt.config('clean.compiledFile.src', filepath.replace('src\\', '')); 
    } 
}); 

Jetzt kopieren von ES6-Dateien sowie Nicht-LESS/Nicht-ES6-Dateien wird nur auftreten, wenn 'src' neuer als 'dest ist.'

Leider hat grunt-neuere nicht wirklich Unterstützung für die Synchronisierung einer Löschoperation, wenn aus' src 'gelöscht. Also verwende ich weiterhin meinen vorherigen Code für "Lösch" -Operationen. Diese hat immer noch den gleichen Fehler wo nach einem Löschen die Watch-Task für einen Moment nicht mehr funktioniert.

Verwandte Themen