LiveReload на Node.js

    Что это такое?


    LiveReload — это утилита, которая позволяет автоматически перезагружать страницу в браузере при изменение её кода и ресурсов(html, css, js, images, etc) на сервере. Кроме того LiveReload позволяет применять изменения в CSS и JavaScript без перезагрузки страницы.


    Зачем это нужно?


    Для удобства разработки клиентской части приложения и не более. Как написано на официальной странице утилиты:
    The Web Developer Wonderland (a happy land where browsers don't need a Refresh button)


    Как это работает?


    Принцип очень прост, утилита состоит из сервера и клиента:
    1. Cервер: WebSocket который мониторит изменения в заданных файлах и если такие изменения обнаружены — уведомляет клиента
    2. Клиент, есть несколько вариантов:
      • Дополнение для браузера которое обновляет страницу.
      • JavaScript сниппет, который слушает WebSocket сервер и при необходимости обновляет страницу. Его необходимо вставить в свои HTML файлы.



    Node.js, huh?


    Если Вы уже используете Node.js или Grunt.js, или хотите чтобы один метод LiveReload'а работал на всех платформах без изменений(LiveReload можно настроить и на Windows и на Linux и на MacOS X, но метод настройки везде разный) то можно использовать grunt-reload.
    Итак, вот что понадобиться:
    1. Node.js. На Убунте к примеру ставим так:
            sudo apt-get install nodejs npm

    2. Grunt.js
            sudo npm install -g grunt

    3. Grunt плагин grunt-reload
            npm install grunt-reload --save-dev



    Плагин grunt-reload кроме двух уже указанных способов livereload'a имеет еще пару вариантов:
    1. Proxy: создает сервер, который будет проксировать запросы к dev. серверу добавляя к HTML файлам livereload сниппет. Избавляет от необходимости вручную обновлять html'ки для поддержки livereload.
    2. iFrame: идентичен предыдущему методу, только вместо автоматического добавления сниппета, открывает страницы в iFrame, который перезагружает их при необходимости. И ваши html'ки останутся чистыми!;)

    К сожалению, grunt-reload не поддерживает применение CSS и JS без перезагрузки всей страницы. Точнее поддерживает, но только с использованием LiveReload browser extension.


    Как использовать


    Создаем проект, в корне создаем grunt.js и в нем настраиваем задачу watch(она будет мониторить изменения в файлах) и задачу reload(при изменении файлов делаем livereload).

    Например, имеем такой express.js проект:
    /public — статика(CSS, images, JS, templates, etc)
    app.js — express.js application
    grunt.js — Gruntfile

    grunt.js выглядит так:

    module.exports = function(grunt) {
    
      grunt.loadNpmTasks('grunt-bg-shell');
      // подключаем grunt-reload
      grunt.loadNpmTasks('grunt-reload');
    
      // Project configuration.
      grunt.initConfig({
        bgShell: {
          //Запускаем приложение с помощью supervisor'a
          //Теперь при изменении серверного кода 
          //сервер перезапускается автоматически
          supervisor: {
                cmd: 'supervisor app.js',
                stdout: true,
                stderr: true,
                bg: true
          }
        },
        //настраиваем reload
        //сервер приложения крутится на localhost:3000
        //переходим на localhost:6001 и получаем то же приложение только с LiveReload
        reload: {
          port: 6001,
          proxy: {
            host: 'localhost',
            port: 3000
          },
        },
        watch: {
          //при изменении любого из этих файлов запустить задачу 'reload'
          files: [
            //add here static file which need to be livereloaded
            'public/styles/**/*.css',
            'public/scripts/**/*.js',
            'public/images/**/*',
            ],
          tasks: 'reload'
        }
      });
    
      //стартуем приложение
      //reload и на клиенте и на сервере
      grunt.registerTask('server', 'bgShell:supervisor reload watch');
    };  
    


    Теперь из корневого каталога приложения можно запустить команду
    grunt server

    И получить автоматически перезапускаемый сервер и LiveReload на клиенте по адресу localhost:6001

    Данный Gruntfile так-же использует пакет supervisor(для мониторинга сервера), и пакет grunt-bg-shell для запуска супервизора в бэкграунде
      sudo npm install -g supervisor
      npm install grunt-bg-shell --save-dev
    

    Share post

    Comments 17

      0
      Сложновато все.

      1. Берем ихний плагин
      2. Cтавим гем guard-livereload
      3. Делаем файлик Guardfile вида

      guard 'livereload' do
        watch(%r{views/.+\.jade$})
        watch(%r{public/.+\.(css|js|html)})
      end
      


      4. guard start

      Полного релоада так конечно не добиться, но статику обновляет
        +1
        Во-первых, если разрабатываете на Node.js, не обязательно ставить RubyGems. А вот Grunt стоит почти наверняка(Вы же не разрабатываете на Ruby без Rake? =)
        Во-вторых, как на счет кросс-платформенности у guard и guard:livereload? На Винде работать будут?

        Кроме того я не видел способа автоматического добавления JS сниппета в html'ки(не считая LiveReload browser extension). Он присутствует?
        Решение с grunt-reload можно с легкостью ужать до тех же 4 строк что и у Вас, у меня просто насыщенный пример =)

        А в принципе особой разницы нет, просто у Вас Руби скрипт, а у меня Нода)
          0
          Согласен, может у вас даже покруче будет, интеграция и все такое — по крайней мере не надо отдельно стартовать вотч и сервер.

          А насчет руби для меня нет религиозной проблемы пользоваться гемами — ну руби ну и что, это не мешает мне им пользоваться в проектах на ноде ) Про винду не знаю — стараюсь не иметь с ней дела, на остальных осях проблем нет.

          В любом случае спасибо, для меня один способ хорошо, а два — лучше
            0
            Дело не в религии, дело в лени. Вы бы знали как иногда лень запустить apt-get и поставить руби.

            И Вам спасибо на добром слове.
        0
        Интересно, а как обеспечивается корретное обновление JS без перезагрузки страницы?
          0
          Пытался откопать в коде, но увы нашел только СSS и картинки. Рою дальше.
          Могу предположить что чистится Global scope, и все скрипты загружаются заново.
            0
            ИМХО так можно довольно забавные баги словить, что дает фичу довольно сомнительной.
            Автоматическое добавление к страницам JS для релоада происходит в прокси?
              0
              Можно, но я только предположил. Возможно мы чего-то не знаем =).
              Да grunt-reload server при проксировании добавляет во все html'ки js сниппет. И в браузере вы идете не по адресу сервера, а по адресу прокси.
                0
                Ясно. У меня одно страничное приложения и вот только в пятницу сам с нуля реализовал релоад страницы с помощью модулей socket.io и watch.
                В принципе если использовать вебсокеты — то реалод это частный случай эвента от сервера.
            0
            И почему supervisor а не скажем forever? (Насколько понял 1й не развивается более.)
              0
              Forever тоже особо не развивается. Последнее время пользуюсь node-dev(он в убунте показывает уведомления через libnotify). Как по мне для девелопмента никакой разницы, хоть node-dev, хоть supervisor, хоть nodemon. Все они делают одно и то же, и достаточно хорошо. А что касается production — то тут уже отдельный разговор и ни одна из этих либ там не нужна.
                0
                Да речь о разработке, хотя вот небольшой сервер с supervisor крутится уже с почти 5 мес аптаймом. Правда там почти нет логики кроме как записывать эвенты в MongoDB. ^)
                  0
                  Кхм… И почему supervisor а не скажем forever? =)

                  Как говорится: «Работает — не трожь!»
                    0
                    Когда этот сервер писался альтернатив супервизору не было :)
                    Ну и да, при разработке никаких проблем не было — так и ушло в использование :))
                    Первый опыт с нодой был.
            0
              0
                0

                Only users with full accounts can post comments. Log in, please.