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

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

Ответ 1

Вы можете создать 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, чтобы просмотреть журналы.

Ответ 2

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

Вы можете просто заменить gulp на gulper.

$ gulper <task-name>

Ответ 3

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

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

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

Bash shell script:

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

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

@echo off
:label
cmd /c gulp watch
goto label

Ответ 4

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

Здесь аналогичное решение, которое затрагивает проблему сосуществования (в основном на этом):

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.

Ответ 5

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

Ответ 6

Я знаю, что это очень старый вопрос, но это главный комментарий к 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() ;
        } ) )
    ;
} ) ;

Он работает следующим образом:

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

Существует много других способов вставки функции перезапуска в трубы. Я просто использую gulp -data в каждом из моих gulpfiles. Не стесняйтесь комментировать свое решение.:)

Ответ 7

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

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

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

Задачей по умолчанию Gulp будет создатель:

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

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

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

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

Ответ 8

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

Ответ 9

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

  • npm install nodemon -g (или локально, если вы предпочитаете)
  • запустите с cmd или создайте script в следующих пакетах: "dev": "nodemon --watch gulpfile.js --exec gulp"
  • Просто тип npm run dev

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

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

РЕДАКТИРОВАТЬ: Сделать это фантазией;) Теперь, когда первая часть должна достичь того, что вам нужно, в моей настройке мне нужно было добавить немного больше, чтобы сделать ее настоящим пользователем. Я хотел был

  • Сначала откройте страницу.
  • Ищите изменения в gulpfile.js и перезапустите gulp, если есть
  • Gulp его следует следить за файлами, перестраивать и перезагружать

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

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"

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

Ответ 10

Установить 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,...), но не для задач с одним запуском. Я имею в виду, что он использует часы, поэтому он продолжит процесс даже после выполнения задачи gulp.;)

Ответ 11

Хорошее решение для 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 завернут в пакетный script. Убив пакет script, он не убьет gulp, что вызовет появление нескольких часов со временем.
  • Настроить на изменение: Обычно изменение gulpfile также гарантирует восстановление проекта.

Ответ 12

Здесь короткая версия, которая легко понять, что вы можете установить как задачу по умолчанию, поэтому вам просто нужно ввести "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']);

Ответ 13

Установить 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