web-dev-qa-db-fra.com

Comment peut-on redémarrer Gulp à chaque changement de fichier Gulpfile?

Je développe une Gulpfile. Peut-on le faire redémarrer dès que cela change? Je le développe en CoffeeScript. Gulp peut-il regarder Gulpfile.coffee afin de redémarrer lorsque les modifications sont enregistrées?

63
coool

Vous pouvez créer une variable task qui sera gulp.watch pour gulpfile.js et simplement spawn autre gulp processus_enfant .

var gulp = require('gulp'),
    argv = require('yargs').argv, // for args parsing
    spawn = require('child_process').spawn;

gulp.task('log', function() {
  console.log('CSSs has been changed');
});

gulp.task('watching-task', function() {
  gulp.watch('*.css', ['log']);
});

gulp.task('auto-reload', function() {
  var p;

  gulp.watch('gulpfile.js', spawnChildren);
  spawnChildren();

  function spawnChildren(e) {
    // kill previous spawned process
    if(p) { p.kill(); }

    // `spawn` a child `gulp` process linked to the parent `stdio`
    p = spawn('gulp', [argv.task], {stdio: 'inherit'});
  }
});

J'ai utilisé yargs pour accepter la "tâche principale" à exécuter une fois que nous devons redémarrer. Donc, pour exécuter ceci, vous appelez:

gulp auto-reload --task watching-task

Et pour tester, appelez soit touch gulpfile.js ou touch a.css pour voir les journaux.

58
Caio Cunha

J'ai créé gulper qui est un wrapper cli gulp.js pour redémarrer gulp lors du changement de fichier gulp.

Vous pouvez simplement remplacer gulp par gulper.

$ gulper <task-name>
36
anatoo

J'utilise un petit script Shell à cette fin. Cela fonctionne aussi sous Windows. 

Appuyez sur Ctrl+C pour arrêter le script.

// gulpfile.js
gulp.task('watch', function() {
    gulp.watch('gulpfile.js', process.exit);
});

Script Bash Shell:

# watch.sh
while true; do
    gulp watch;
done;

Version Windows: watch.bat

@echo off
:label
cmd /c gulp watch
goto label
11
Simon Epskamp

Je recevais un tas d'erreurs EADDRINUSE avec la solution de la réponse de Caio Cunha. Mon gulpfile ouvre un serveur Web local avec connect et LiveReload . Il semble que le nouveau processus d’abattement coexiste brièvement avec l’ancien avant que l’ancien processus ne soit tué, de sorte que les ports sont toujours utilisés par le processus qui va bientôt mourir.

Voici une solution similaire qui résout le problème de la coexistence (basée en grande partie sur this ):

var gulp = require('gulp');
var spawn = require('child_process').spawn;

gulp.task('gulp-reload', function() {
  spawn('gulp', ['watch'], {stdio: 'inherit'});
  process.exit();
});

gulp.task('watch', function() {
  gulp.watch('gulpfile.js', ['gulp-reload']);
});

Cela fonctionne assez bien, mais a un effet secondaire assez sérieux: Le dernier processus de groupement est déconnecté du terminal. Ainsi, lorsque gulp watch se ferme, un processus de groupement orphelin est toujours en cours d'exécution. Je n'ai pas été en mesure de contourner ce problème, le processus supplémentaire gulp peut être supprimé manuellement ou tout simplement enregistrer une erreur de syntaxe dans gulpfile.js.

9
joemaller

Une autre solution consiste à actualiser le require.cache

var gulp = require('gulp');

var __filenameTasks = ['lint', 'css', 'jade'];
var watcher = gulp.watch(__filename).once('change', function(){
  watcher.end(); // we haven't re-required the file yet
                 // so is the old watcher
  delete require.cache[__filename];
  require(__filename);
  process.nextTick(function(){
    gulp.start(__filenameTasks);
  });
});
3
stringparser

Je sais que c'est une très vieille question, mais c'est un commentaire important sur Google, donc toujours très pertinent. 

Voici un moyen plus simple si votre source gulpfile.js est dans un répertoire différent de celui utilisé. (C'est important!) Il utilise les modules gulp gulp-newer et gulp-data .

var gulp          = require('gulp'         )
  , data          = require('gulp-data'    )
  , newer         = require('gulp-newer'   )
  , child_process = require('child_process')
;

gulp.task( 'gulpfile.js' , function() {
    return gulp.src( 'sources/gulpfile.js' ) // source
        .pipe( newer(     '.'            ) ) // check
        .pipe( gulp.dest( '.'            ) ) // write
        .pipe( data( function(file)        { // reboot
            console.log('gulpfile.js changed! Restarting gulp...') ;
            var t , args = process.argv ;
            while ( args.shift().substr(-4) !== 'gulp' ) { t=args; }
            child_process.spawn( 'gulp' , args , { stdio: 'inherit' } ) ;
            return process.exit() ;
        } ) )
    ;
} ) ;

Cela fonctionne comme ceci:

  • Astuce 1: gulp-newer n'exécute les canaux suivants que si le fichier source est plus récent que le fichier actuel. De cette façon, nous nous assurons qu'il n'y a pas de boucle de redémarrage.
  • La boucle while supprime tout ce qui précède et y compris la commande gulp de la chaîne de commande afin que nous puissions passer à travers tous les arguments.
  • child_process.spawn génère un nouveau processus gulp, transmettant une entrée en sortie et une erreur au parent.
  • Astuce 2: process.exit supprime le processus en cours. Cependant, le processus attendra de mourir jusqu'à ce que le processus enfant soit terminé.

Il y a beaucoup d'autres façons d'insérer la fonction de redémarrage dans les tuyaux. De toute façon, j’arrive d’utiliser des données gulp dans chacun de mes fichiers gulp. N'hésitez pas à commenter votre propre solution. :)

2
bid

Installer nodemon globalement: npm i -g nodemon

Et ajoutez dans votre .bashrc (ou .bash_profile ou .profile) un alias:

alias gulp='nodemon --watch gulpfile.js --watch gulpfile.babel.js --quiet --exitcrash --exec gulp'

Cela surveillera les modifications des fichiers gulpfile.js et gulpfile.babel.js. (voir Google )

P.S. Cela peut être utile pour des tâches sans fin (comme watch) mais pas pour des tâches à exécution unique. Je veux dire, il utilise watch pour continuer le processus même une fois que la tâche gulp est terminée. ;)

1
Davit Yavryan

essayez ce code (seulement la plate-forme win32)

gulp.task('default', ['less', 'scripts', 'watch'], function(){
    gulp.watch('./gulpfile.js').once('change' ,function(){
        var p;
        var childProcess = require('child_process');
        if(process.platform === 'win32'){
            if(p){
                childProcess.exec('taskkill /PID' + p.id + ' /T /F', function(){});
                p.kill();
            }else{
                p = childProcess.spawn(process.argv[0],[process.argv[1]],{stdio: 'inherit'});
            }
        }
    });
});
1
AhbapAldirmaz

Une bonne solution pour Windows, qui fonctionne également bien avec le lanceur de tâches Visual Studio.

/// <binding ProjectOpened='auto-watchdog' />
const spawn = require('child-proc').spawn,
      configPaths = ['Gulpconfig.js', 'bundleconfig.js'];

gulp.task('watchdog', function () {
    // TODO: add other watches here

    gulp.watch(configPaths, function () {
        process.exit(0);
    });
});

gulp.task('auto-watchdog', function () {
    let p = null;

    gulp.watch(configPaths, spawnChildren);
    spawnChildren();

    function spawnChildren() {
        const args = ['watchdog', '--color'];

        // kill previous spawned process
        if (p) {
            // You might want to trigger a build as well
            args.unshift('build');

            setTimeout(function () {
                p.kill();
            }, 1000);
        }

        // `spawn` a child `gulp` process linked to the parent `stdio`
        p = spawn('gulp', args, { stdio: 'inherit' });
    }
});

Principaux changements par rapport aux autres réponses:

  • Utilise child-proc car child_process échoue sous Windows.
  • Le chien de garde se ferme sur les modifications de fichiers car dans Windows l'appel gulp est encapsulé dans un script batch. Tuer le script batch ne tuerait pas une gorgée, ce qui entraînerait l'apparition de plusieurs montres au fil du temps.
  • Construire sur le changement: Généralement, un changement de fichier gulp justifie également la reconstruction du projet.
1
Sebazzz

Voici une autre version du code de rechargement de @ CaioToOn qui est plus conforme à la procédure de tâche Gulp normale. Cela ne dépend pas non plus de yargs.

Requiert spawn et initilaize la variable de processus (yargs n'est pas nécessaire):

var spawn = require('child_process').spawn;
var p;

La tâche d'abattage par défaut sera le géniteur:

gulp.task('default', function() {
  if(p) { p.kill(); }
  // Note: The 'watch' is the new name of your normally-default gulp task. Substitute if needed.
  p = spawn('gulp', ['watch'], {stdio: 'inherit'});
});

Votre tâche de surveillance était probablement votre tâche de groupe par défaut. Renommez-le watch et ajoutez une gulp.watch()pour surveiller votre fichier gulp et exécutez la tâche default sur les modifications:

gulp.task('watch', ['sass'], function () {
  gulp.watch("scss/*.scss", ['sass']);
  gulp.watch('gulpfile.js', ['default']);
});

Maintenant, lancez simplement gulp et il sera automatiquement rechargé si vous modifiez votre fichier gulp!

1
ddunderfelt

Je suis confronté au même problème et la solution dans mon cas était en réalité très simple. Deux choses.

  1. npm install nodemon -g (ou localement si vous préférez)
  2. exécutez avec cmd ou créez un script dans des packages comme celui-ci:

    "dev": "nodemon --watch gulpfile.js --exec gulp"
    
  3. Le juste tapez npm run dev

--watch spécifie le fichier à surveiller. --exec indique exécuter suivant en ligne et gulp est votre tâche par défaut. Passez juste en argument si vous voulez une tâche non par défaut.

J'espère que ça aide. 

EDIT: Donner envie;) Maintenant, alors que la première partie devrait réaliser ce que vous recherchiez, dans ma configuration, j’ai eu besoin d’ajouter un peu plus pour en faire un ami vraiment utilisateur. Ce que je voulais, c'était

  1. Commencez par ouvrir la page.
  2. Recherchez les modifications dans gulpfile.js et redémarrez gulp s’il en existe
  3. Gulp it up donc gardez un œil sur les fichiers, reconstruisez et rechargez à chaud

Si vous ne faites que ce que j'ai dit dans la première partie, la page s'ouvrira à chaque fois. Pour résoudre ce problème, créez une tâche de groupe qui ouvrira la page. Comme ça :

gulp.task('open', function(){
return gulp
.src(config.buildDest + '/index.html')
.pipe(plugins.open({
    uri: config.url
}));

Ensuite, dans mes tâches principales, j'ai: 

gulp.task('default', ['dev-open']);
gulp.task('dev-open', function(done){
    plugins.sequence('build', 'connect', 'open', 'watch', done);
});
gulp.task('dev', function(done){
    plugins.sequence('build', 'connect', 'watch', done);
});

Puis en modifiant vos scripts npm pour 

"dev": "gulp open & nodemon --watch gulpfile.js --watch webpack.config.js --exec gulp dev"

Vous donnera exactement ce que vous voulez. Commencez par ouvrir la page, puis continuez à recharger en direct. Btw pour livereload j'utilise celui qui vient avec connect qui utilise toujours le même port. J'espère que cela fonctionne pour vous, profitez-en!

1
Peter Kottas

Installez gulp-restart

npm install gulp-restart

Ce code fonctionnera pour vous.

var gulp = require('gulp'); var restart = require('gulp-restart');

gulp.task('watch', function() { gulp.watch(['gulpfile.js'], restart); })

il va redémarrer gulp où vous apportez des modifications sur le fichier gulpfile.js

0

Voici une version courte, facile à comprendre, que vous pouvez définir comme tâche par défaut.

gulp.task('watch', function() {
  const restartingGulpProcessCmd = 'while true; do gulp watch2 --colors; done;';
  const restartingGulpProcess = require('child_process').exec(restartingGulpProcessCmd);
  restartingGulpProcess.stdout.pipe(process.stdout);
  restartingGulpProcess.stderr.pipe(process.stderr);
});

gulp.task('watch2', function() {
  gulp.watch(['config/**.js', 'webpack.config.js', './gulpfile.js'],
    () => {
      console.log('Config file changed. Quitting so gulp can be restarted.');
      process.exit();
    });

  // Add your other watch and build commands here
}

gulp.task('default', ['watch']);
0
fstr