Grunt: `contrib-watch` Запускает событие livereload после перезагрузки`grunt-nodemon` при компиляции файлов на стороне сервера `.coffee`

У меня возникла проблема с Grunt.js и несколькими плагинами, а именно: grunt-contrib-watch, grunt-nodemon а также grunt-contrib-coffee, Я пытался выяснить это уже два дня, но я не думаю, что мои знания о Гранте достаточны, чтобы решить это на данный момент.

Проблема, с которой я сталкиваюсь, заключается в том, что я просто хочу, чтобы моя серверная часть .coffee файлы для компиляции, а затем с помощью nodemon перезагружают сервер, а ТОЛЬКО работают livereload Прямо сейчас Livereload работает так, как задумано для всего, кроме серверной части. coffee файлы. contrib-watch обнаруживает изменение, работает coffee и выстреливает livereload событие, но потом nodemon перезагружается.

Есть ли способ получить nodemon перезапустить до перезагрузки страницы, чтобы то, что я вижу на экране, соответствовало тому, что происходит в моем коде на стороне сервера?

Мне предложили возможность просто бежать nodemon в отдельной вкладке терминала, но я на Windows и предпочел бы, чтобы один терминал работал для этой цели, и именно по этой причине я использую grunt-concurrent,

Вот мой Gruntfile, он находится на довольно ранней стадии (так как я пытаюсь все это выяснить). Если вы предпочитаете, чтобы я компилировал его в JavaScript, то просто оставьте комментарий и запросите, поэтому я буду рад.

module.exports = (grunt) ->

  # configuration
  grunt.initConfig
    pkg: grunt.file.readJSON 'package.json'

    # watch task
    watch:
      css:
        files: ['src/assets/styles/**/*.styl']
        tasks: ['stylus']
        options:
          livereload: true
      coffee:
        files: ['src/**/*.coffee']
        tasks: ['coffee']
      js:
        files: ['**/*.js']
        options:
          livereload: true
      jade:
        files: ['views/**/*.jade']
        options:
          livereload: true

    # compile coffeescript to javascript
    coffee:
      compile:
        options:
          sourceMap: true
        files: [
          expand: true
          cwd: 'src/'
          src: ['**/*.coffee']
          dest: ''
          ext: '.js'
        ]

    # compile stylus to css
    stylus:
      compile:
        files: [
          expand: true
          cwd: 'src/assets/styles/'
          src: ['**/*.styl']
          dest: 'assets/styles/'
          ext: '.css'
        ]

    # run server
    nodemon:
      dev:
        options:
          file: 'server.js'
          watchedExtensions: ['js', 'json']
          ignoredFiles: [
            'assets/**',
            'node_modules/**',
            '**/.js.map'
          ]

    # run tasks concurrently for fast builds
    concurrent:
      first:
        tasks: ['coffee', 'stylus']
        options:
          logConcurrentOutput: true
      second:
        tasks: ['nodemon', 'watch']
        options:
          logConcurrentOutput: true

  # load dependencies
  require('load-grunt-tasks') grunt

  # register tasks
  grunt.registerTask 'default', [
    'concurrent:first',
    'concurrent:second'
  ]

4 ответа

Решение

Я не использовал это сам, но я столкнулся с этим некоторое время назад: grunt-rerun, В сочетании с задачей наблюдения вы можете приостановить долгосрочную задачу, такую ​​как экспресс (но, вероятно, будет работать и с nodemon), запустить некоторые задачи, а затем снова запустить задачу. Пример конфигурации выглядит так:

grunt.initConfig({
  watch: {
      dev: {
        files: ['server/*.js'],

        //Note the :go flag used for sending the reload message to the rerun server
        tasks: ['clean','rerun:dev:express:go']
      },
    },
    express: {
        dev: {
            options: {
                port: 3000,
                bases: ['/public'],
                keepalive: true,
                server: path.resolve('./server/app.js')
            }
        }
    },
    // Configuration to be run (and then tested).
    rerun: {
      dev: {
        options: {
          tasks: ['express']
        },
      },
    }
})

https://npmjs.org/package/grunt-rerun

Я не совсем уверен насчет живой перезагрузки. Мое предположение могло бы быть, потому что это закрывает процесс, порождая новый, он загружал бы страницу заново, но я не использовал это лично, поэтому я не уверен.

Второй вариант - да, использовать командную строку, которая поддерживает несколько вкладок, например консоль. Я пользователь Mac и поэтому использую iTerm 2, который имеет несколько панелей; Большую часть времени у меня есть четыре открытых для проекта, для watch, testem, php сервер и оболочка для всего остального. Вы можете обнаружить, что это намного быстрее и намного меньше хлопот.

Просто краткая заметка о Coffeescript, многие разработчики JavaScript не используют его, поэтому, чтобы более широкая аудитория могла понять ваш исходный код, может быть полезно скомпилировать кофе в js перед тем, как вы отправите свой вопрос.

Я использовал watch для просмотра файлов на сервере и простую задачу "2SecDelay", которая дает нодмону время для перезапуска сервера.

Итак, я получил патч, но это ужасно

grunt.registerTask '2SecDelay', 'just taking some time', ->
  done = @async()
  setTimeout((() -> done()), 2000)

...

nodemon:
  server:
    ... run server and watch server related files ...
watch:
  server: 
    files: ... same files as the nodemon watches ...
    tasks: ['2SecDelay']
concurrent:
  server:
    ['nodemon', 'watch']

```

Зачем вам в реальном времени перезагружать файлы кофе / стилуса / нефрита?

Просто обновите скомпилированные изменения! Я предполагаю, что у вас есть общая папка с скомпилированным выводом из ваших файлов.coffee/.styl/.jade

Это мой пример Gruntfile:

module.exports = (grunt) ->
  grunt.config.init
    ...

    watch:
      css:
        files: ['src/assets/styles/**/*.styl']
        tasks: ['stylus']
      coffee:
        files: ['src/**/*.coffee']
        tasks: ['coffee']
      jade:
        files: ['views/**/*.jade']
      livereload:
        files: ['public/**/*.*']
        options:
          livereload: true
    ...

Таким образом, вы также будете запускать прямую загрузку для изменений не файлов js / css, таких как изображения, шрифты и так далее. И вы всегда уверены, что livereload будет запущен

Я добавил следующий http-запрос к tiny-lr при запуске моего сервера.

var server = app.listen(process.env.PORT || 3000, function() {
  debug('Koa server listening on port ' + server.address().port);

  require('http').get({host: 'localhost', port: 35729, path: '/changed?files=app.js'},      
     function (response){
        console.log('Restart');
  });
});

У меня есть Webstorm, в котором работает nodemon, так что это кажется простым способом связи между nodemon и реализацией сервера livereload, которую я использую.

Я попытался запустить nodemon из задачи Gulp и получить там http-вызов, чтобы сохранить мой код в чистоте, но кажется, что nodemon не вызывает событие, которое запускается после запуска сервера - его событие restart срабатывает перед перезапуском.

Кажется, что собственное событие прослушивания приложения является лучшим местом для запуска обновления, поскольку вы знаете, что в этот момент сервер готов начать обработку запросов.

Это не технологии, указанные в вопросе, но принцип должен применяться точно так же.

Другие вопросы по тегам