2016-06-03 33 views
9

sto sviluppando un progetto dattiloscritto con le seguenti operazioni costruire:orologio Gulp termina o costruisce l'intera catena compito

  • lint
  • accumulo
  • prova

Sto usando Gulp 4.0 come strumento di compilazione e si desidera avere un'attività di controllo, che dovrebbe attivare il test (il che significa che i task lint e build sono stati attivati ​​prima). Attualmente, quando si verifica un errore (ad esempio un errore di sfilacciamento), l'attività di controllo termina.

Questo problema è ben noto e facile da risolvere. La soluzione tipica è a) per evitare errori o b) per correggere il comportamento del tubo.

a) Per la gulp-tslint ho potuto utilizzare questo config da loro homepage:

gulp.task("invalid-noemit",() => 
    gulp.src("input.ts") 
     .pipe(tslint()) 
     .pipe(tslint.report("prose", { 
      emitError: false 
     })) 
); 

Ma quando includo la bandiera emitError, gli errori pelucchi vengono registrati e vengono eseguiti tutti i seguenti compiti gulp (build, test) .

b) Potrei anche utilizzare gulp-plumber o rilevare errori manualmente (vedere here), ma il comportamento è lo stesso per tutte queste soluzioni note, vengono eseguite le seguenti attività di gulp (build, test).

Quello che voglio è che la catena di attività si fermi dopo un errore (nessuna generazione e test dopo un errore di sfilacciamento), ma l'attività di controllo non dovrebbe mai fermarsi. Come potrei risolvere questo? I compiti watcher simile a questa:

// watcher 
gulp.task('watch', gulp.series('test', function doWatch() { 
    gulp.watch([ 
     config.paths.sourcePattern, 
     config.paths.testPattern, 
     'gulpfile.js' 
    ], gulp.parallel('test')); 
})); 

È possibile trovare la completa gulpfile.jshere.

+0

Potrebbe pubblicare il tuo compito orologio? –

+0

Ho aggiornato la domanda con l'attività di controllo. – ChrLipp

+0

è lo stesso se si utilizza gulp.series ('lint', 'build', 'test') sull'attività di controllo, invece di dipendere direttamente dagli altri? – YOU

risposta

2

Il motivo per cui l'orologio si interrompe è perché un oggetto err viene propagato sulla catena di richiamata. È necessario impedire che err raggiunga la callback finale gulp.watch().

Potete farlo avvolgendo il callback fornito da gulp.watch() e mai passando l'oggetto err al callback originale:

gulp.task('watch', function() { 
    gulp.watch([ 
     config.paths.sourcePattern, 
     config.paths.testPattern, 
     'gulpfile.js' 
    ], {ignoreInitial:false}, function(cb) { 
     gulp.series('lint', 'build', 'test')(function wrappedCb(err) { 
     cb(); // not passing err here 
    }); 
    }); 
}); 

Nota che gulp.series('lint', 'build', 'test') in realtà non eseguire i compiti. Restituisce semplicemente una nuova funzione che accetta una richiamata. Solo quando questa nuova funzione è invocata come gulp.series('lint', 'build', 'test')() sono le attività effettivamente eseguite.

Ho anche aggiunto l'opzione ignoreInitial in modo che l'orologio venga eseguito una volta dopo l'avvio che sembra essere quello che stai cercando di ottenere con gulp.series('test', ...) nell'attività watch.

(a parte: guarda gulpfile.js è inutile modifiche al gulpfile non avranno effetto fino a quando si esegue nuovamente gulp watch Non c'è modo per aggirare questo...)


Infine, è necessario disaccoppiare le nostre altre attività, in modo da non hanno dipendenze esplicite su altre attività. Si è tentati di tradurre un sorso 3.x compito come questo:

gulp.task('foo', ['bar'], function() { }); 

in un compito sorso 4.x in questo modo:

gulp.task('foo', gulp.series('bar', function() { })); 

sembrano simili in superficie, ma sono del tutto diversa sotto il cofano. Vedi this article per ulteriori informazioni su questo argomento.

Una buona strategia è quella di organizzare le attività in due categorie:

  1. attività autonome che fare una cosa e non dipendono da altri compiti.
  2. Operazioni composite che eseguono diverse altre attività in serie o in parallelo.

Seguendo questo principio gli altri compiti possono essere riscritta in questo:

gulp.task('lint', function() { 
    return gulp.src([ 
    config.paths.sourcePattern, 
    config.paths.testPattern 
    ]) 
    .pipe(tslint()) 
    .pipe(tslint.report('verbose', { 
    emitError: true, // we WANT to emit this err so our other tasks don't run 
    summarizeFailureOutput: true 
    })); 
}); 

gulp.task('build-app', function doBuildApp() { 
    /* ... */ 
}); 

gulp.task('build-test', function doBuildTest() { 
    /* ... */ 
}); 

gulp.task('build', gulp.series('lint', 'build-app', 'build-test')); 

gulp.task('test', gulp.series(function doPreTest() { 
    /* ... */ 
    }, function doTest() { 
    /* ... */ 
    }, function doPostTest() { 
    /* ... */ 
})); 
+0

So come impedire l'arresto dell'attività di controllo, la domanda è come impedire l'esecuzione di build e test quando si verifica un errore di lint (o l'esecuzione del test, quando si verifica un errore di compilazione). – ChrLipp

+0

Hai provato la mia soluzione? Perché fa esattamente questo. L'attività 'lint' emette un oggetto' err', che impedisce 'build' e' test' di funzionare. Ma err = non viene passato a 'cb', il che significa che l'orologio non si ferma. –

+0

Ho provato la soluzione. L'unica differenza era che non avevo filato, costruito e testato nella serie, perché il lint è un prerequisito di costruzione e la costruzione è un prerequisito del test. Perciò ho fatto solo dei test nella serie e questo ha portato a un'esecuzione di tutti i passaggi. A proposito, perché 'gulp.series()()' funziona, potresti spiegarlo? – ChrLipp