2015-09-01 21 views
14

Ho due directory src e compiled. Vorrei garantire la sincronizzazione dei dati unidirezionali da src a compiled con Grunt Watch. Come passaggio intermedio, vorrei compilare i file *.less e un sottoinsieme di file *.js scritti con la sintassi ES6.Deep, sincronizzazione unidirezionale di due directory usando grunt-contrib-watch. Il codice funziona, ma il tempo di re-init di grunt-contrib-watch è troppo lento

ho scritto con successo i compiti che faccio quello che mi serve:

// 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\\', '')); 
    } 
    }); 

Questi compiti guardare i file appropriati. Il gestore eventi modifica dinamicamente le attività cleancopy e babel in modo tale che funzionino sui file da aggiungere/modificare/rimuovere.

Tuttavia, sto guardando diverse migliaia di file e l'operazione di controllo richiede una quantità non trascurabile di tempo per l'inizializzazione. Sul mio PC di sviluppo di fascia alta l'inizializzazione impiega 6+ secondi. Questo problema è esacerbato dal fatto che l'attività di controllo viene reinizializzata dopo ogni attività.

Questo significa che se ho due file, fileA e fileB, e modifico fileA e salvo poi c'è un secondo periodo in cui 6+ orologio non riesce a rilevare le modifiche al fileB. Ciò comporta la de-sincronizzazione tra le mie due directory.

ho trovato questo problema GitHub per quanto riguarda il mio problema, ma è ancora aperta e senza risposta: https://github.com/gruntjs/grunt-contrib-watch/issues/443

La discussione su GitHub mette in evidenza che il problema può verificarsi solo quando spawn: false è stato impostato, ma, secondo il Grunt Watch documentation:

Se è necessario modificare dinamicamente la configurazione, l'opzione di spawn deve essere disabilitata per mantenere l'orologio in esecuzione nello stesso contesto.

Come tale, credo di dover continuare a utilizzare spawn: false.

Devo supporre che questa sia una procedura abbastanza standard per le attività di Grunt. Mi sto perdendo qualcosa di ovvio qui? L'attività dell'orologio è inappropriata per questo scopo? Altre opzioni?

+0

Hai dato un'occhiata a [grunt-newer] (https://www.npmjs.com/package/grunt-newer)? Sembra che questo faccia esattamente quello che * lowkay * menziona nel numero aperto. – DavidDomain

+0

Stavo giocando con Grunt-Newer per la scorsa ora o due. Funziona bene per il codice compilato, ma se un file viene copiato da 'src' a 'compilato' senza bisogno di modifiche, l'ora 'ultima modifica' del file non viene aggiornata. Ciò comporta che il file venga incluso ogni volta che viene eseguita l'attività. Se riesco a trovare un modo per risolvere il problema, allora sarà sufficiente grunt-newer. –

+1

Usi [jit-grunt] (https://github.com/shootaroo/jit-grunt)? Ciò aiuterebbe ad accelerare l'attività di vigilanza –

risposta

4

OK, quindi ho una soluzione funzionante, ma è non carina.

Ho terminato utilizzando grunt-newer per assistere con la soluzione. Sfortunatamente, non funziona bene con grunt-contrib-copy perché copiare un file non aggiorna l'ultima volta che è stato modificato e quindi grunt-newer eseguirà il 100% delle volte.

Così, ho biforcato grugnito-contrib-copy e ha aggiunto un'opzione per consentire l'aggiornamento del data dell'ultima modifica: https://github.com/MeoMix/grunt-contrib-copy

Con questo, ora sono in grado di scrivere:

// 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\\', '')); 
    } 
}); 

Now copying dei file ES6 e dei file non LESS/non ES6 si verificano solo se 'src' è più recente di 'dest.'

Sfortunatamente, grunt-newer non ha realmente il supporto per sincronizzare un'operazione di cancellazione quando viene cancellato da' src '. Quindi, continuo a utilizzare il mio codice precedente per le operazioni di "cancellazione". Questo ha ancora lo stesso difetto in cui, dopo l'eliminazione, l'attività di controllo verrà disattivata per un momento.