it-swarm.com.ru

Как можно перезапустить Gulp после каждого изменения в Gulpfile?

Я разрабатываю Gulpfile. Можно ли его перезапустить, как только он изменится? Я разрабатываю это в CoffeeScript. Может ли Gulp просматривать Gulpfile.coffee, чтобы перезапускаться после сохранения изменений?

63
coool

Вы можете создать task, который будет gulp.watch для gulpfile.js и просто spawn другой gulp child_process .

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

Я использовал yargs , чтобы принять «основную задачу» для запуска, как только нам нужно будет перезапустить. Таким образом, чтобы запустить это, вы должны позвонить:

gulp auto-reload --task watching-task

И чтобы проверить, вызовите или touch gulpfile.js или touch a.css, чтобы видеть журналы.

58
Caio Cunha

Я создал gulper , который является оберткой gulp.js для перезапуска gulp при изменении файла gulpfile.

Вы можете просто заменить глоток гулпером.

$ gulper <task-name>
36
anatoo

Я использую небольшой скрипт для этой цели. Это работает и на Windows. 

Нажмите Ctrl+C, чтобы остановить скрипт.

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

Скрипт Bash Shell:

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

Версия для Windows: watch.bat

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

Я получил кучу EADDRINUSE ошибок с решением в ответе Caio Cunha. Мой gulpfile открывает локальный веб-сервер с connect и LiveReload . Похоже, что новый процесс gulp ненадолго сосуществует со старым до того, как старый процесс будет убит, поэтому порты все еще используются процессом, который скоро умрет.

Вот аналогичное решение, которое решает проблему сосуществования (в основном на основе 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']);
});

Это работает довольно хорошо, но имеет один довольно серьезный побочный эффект: Последний процесс gulp отключен от терминала. Таким образом, когда выходит gulp watch, процесс потерянного gulp все еще выполняется. Я не смог обойти эту проблему, лишний процесс gulp можно убить вручную или просто сохранить синтаксическую ошибку в gulpfile.js.

9
joemaller

Другое решение для этого - обновить 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

Я знаю, что это очень старый вопрос, но это главный комментарий в Google, поэтому он все еще очень актуален. 

Вот более простой способ, если ваш исходный файл gulpfile.js находится в в другом каталоге, чем тот, который используется. (Это важно!) Он использует модули gulp gulp-newer и 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() ;
        } ) )
    ;
} ) ;

Это работает так:

  • Трюк 1: gulp-newer выполняет только следующие каналы, если исходный файл новее текущего. Таким образом, мы убедились, что перезагрузки нет.
  • Цикл while удаляет все до и включая команду gulp из командной строки, поэтому мы можем передавать любые аргументы.
  • child_process.spawn порождает новый процесс gulp, передавая выходные данные и сообщения об ошибках родителю.
  • Трюк 2: process.exit убивает текущий процесс. Тем не менее, процесс будет ждать смерти, пока дочерний процесс не будет завершен.

Есть много других способов вставить функцию перезапуска в каналы. В любом случае я просто использую данные gulp в каждом из моих файлов gulpfile. Не стесняйтесь комментировать свое собственное решение. :)

2
bid

Установите nodemon глобально: npm i -g nodemon

И добавьте в свой .bashrc (или .bash_profile или .profile) псевдоним:

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

Это будет следить за изменениями файла gulpfile.js и gulpfile.babel.js. (см. Google )

P.S. Это может быть полезно для бесконечных задач (например, watch), но не для одиночных задач. Я имею в виду, что он использует часы, поэтому он продолжит процесс даже после того, как задание выполнено. ;)

1
Davit Yavryan

попробуйте этот код (только платформа 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

Хорошее решение для Windows, которое также хорошо работает с программой запуска задач 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' });
    }
});

Основные изменения по сравнению с другими ответами:

  • Использует child-proc, потому что child_process не работает в Windows.
  • Сторожевой таймер закрывает себя при изменении файлов, потому что в Windows вызов gulp оборачивается пакетным скриптом. Уничтожение пакетного сценария не убило бы само глоток, что привело бы к появлению нескольких часов с течением времени.
  • Создание изменений: обычно изменение файла gulpfile также требует перестройки проекта.
1
Sebazzz

Вот еще одна версия кода перезагрузки @ CaioToOn, которая больше соответствует обычной процедуре задачи Gulp. Это также не зависит от yargs.

Требовать spawn и инициализировать переменную процесса (yargs не требуется):

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

Задание по умолчанию будет порождать:

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

Ваше задание по наблюдению было, вероятно, заданием по умолчанию. Переименуйте его в watch и добавьте gulp.watch() для просмотра вашего gulpfile и запустите задачу default с изменениями:

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

Теперь просто запустите gulp, и он автоматически перезагрузится, если вы измените свой gulpfile!

1
ddunderfelt

Я имел дело с той же проблемой, и решение в моем случае было очень простым. Две вещи.

  1. npm install nodemon -g (или локально, если вы предпочитаете)
  2. запустить с помощью cmd или создать скрипт в таких пакетах:

    "dev": "nodemon --watch gulpfile.js --exec gulp"
    
  3. Просто введите npm run dev

--watch указывает файл, за которым нужно следить. --exec говорит, что выполнить следующий в строке, и gulp ваша задача по умолчанию. Просто введите аргумент, если вы хотите задачу не по умолчанию.

Надеюсь, поможет. 

Правка: сделать его причудливым;) Теперь, в то время как первая часть должна достичь того, что вы хотели, в моей настройке мне нужно было добавить немного больше, чтобы сделать его действительно удобным для пользователя. Что я хотел

  1. Сначала откройте страницу.
  2. Найдите изменения в gulpfile.js и перезапустите gulp, если они есть.
  3. Проглоти это, так что следи за файлами, перестраивай и перезагружайся

Если вы сделаете только то, что я сказал в первой части, он будет открывать страницу каждый раз. Чтобы исправить это, создайте задание глотка, которое откроет страницу. Как это :

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

Тогда в моих основных задачах я имею: 

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);
});

Затем измените ваши npm-скрипты на 

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

Даст вам именно то, что вы хотите. Сначала откройте страницу, а затем просто продолжайте обновлять. Кстати, для livereload я использую тот, который поставляется с Connect, который всегда использует один и тот же порт. Надеюсь, что это работает для вас, наслаждайтесь!

1
Peter Kottas

Установите gulp-restart

npm install gulp-restart

Этот код будет работать для вас.

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

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

он перезапустит gulp, где вы вносите изменения в gulpfile.js

0
Dilakshan Sooriyanathan

Вот короткая версия, которую легко понять, которую вы можете установить в качестве задачи по умолчанию, поэтому вам просто нужно набрать «gulp»:

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