Pull to refresh

LiveReload в очень постороннем браузере

Reading time 3 min
Views 4.6K
Заморочился я автообновлением странички в браузере на таскаемом с собой iPad при разработке NodeJS/ExpressJS-приложений, чтобы видеть все изменения на лету.
Под катом — как очень просто сделать из мобильного гаджета средство живого просмотра разрабатываемых веб-приложений.

По разным причинам статья LiveReload на Node.js мне не помогла. По каким? Всё просто — там дядьки grunt-ы с gem-ами обсуждают. А я только пришел к NodeJS/Express. Не пугайте меня короче :)

Зачем это надо?


Для удобства, для чего же еще. Пересев на MacBook Air понял, что это тот инструмент, который я хотел. Минусом было недостаточное количество места на мониторе и отсутствие AppleTV для решения сабжа (для его замены заказал Tronsmart T1000 MirrorT2 со значительной скидкой, посмотрим как он справится с задачами, но это уже другая история), хотя идея сидеть перед телевизором для живого созерцания результата деятельности не очень нравится…

Глядя на зоопарк разноплатформенных гаджетов, подумал — а почему бы не попользовать таскаемый всюду вместе с макбуком айпад в качестве отображения творимого? Да еще и чтоб пальцем в иконку не попадать…

Второй монитор из планшета? Нее.


Сначала подумалось — вот же, купить AirDisplay в аппсторе (или его аналог за меньшие деньги, например iDisplay), поставить сервер, и — вуаля. Но это решение несколько иных задач, наверное полезных и нужных. Но не моей.
Тем более Tronsmart уже выслан нашими братьями с поднебесной.

Действуем правильно.


Мне очень не хотелось созерцать результат на десктопном браузере, а хотелось именно в нативном гаджетном (том же Safari).
И очень удачно, что есть решения умельцев для дерганья сервера ноды при изменении файлов проекта (nodemon, supervisor и иже с ними). Забегая вперед: мой выбор пал на supervisor ввиду его более отзывчивой работы.

Хорошо, сервер перезапустится при Command-S / Ctrl-S (кстати, на Windows метод тоже работает). Как теперь заставить браузер освежить контент? И снова краткий гуглеж вывел меня на reload.

Что написано в описании модуля reload:
Node.js module to refresh and reload your code in your browser when your code changes. No browser plugins required.

Отлично, то что нужно. Вооруженный целыми двумя тулзами я и сел за ваяние некоего чуда:

Тестировать будем на чистом express-приложении:
$ express

Тянем зависимости:
$ npm i

Ставим supervisor:
$ npm i supervisor -g

и reload:
$ npm i reload --save-dev

Всё, подготовка окружения закончена.

Теперь нужно подпилить приложение-заготовку согласно документации:

/app.js:
...
var reload = require('reload');
...
var server = http.createServer(app);
reload(server, app);
server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

/views/layout.jade:
head
  script(src='/reload/reload.js');

Запустим наш супер superserver на отслеживание изменений в файлах .jade:
$ supervisor -e jade app.js

и убедимся, что наш «компьютерный» браузер показывает именно то, что мы ждем, по адресу localhost:3000:
image

Для проверки живого общения браузера с сервером, поменяем исходный файл /views/index.jade
extends layout

block content
  h1= title
  p Welcome to #{title}

на:
extends layout

block content
  h1= title
  h2 Привет, хабр!
  p Welcome to #{title}

и получим живое обновление с названием LiveReload:
image

Работает, черт возьми!

Грабелек? Их есть у меня!


На радостях бежим к нашему гаджету, в моем случае к iPad, набираем в адресной строке 0.0.0.0:3000 (ip-адрес машинки с запущенным NodeJS-сервером), получаем ожидаемый результат:
Скрытый текст
image

далее возвращаем код /views/index.jade к исходному, без h2 Привет, хабр!, сохраняем его и… получаем фейл:
Скрытый текст
image

Причем, если страницу обновить руками — всё отобразится как и должно быть. Засада… DeadReload…

От печальки до радости...


Пораскинув мозгами, поковыряв всяко-разно, и ничего не починив и не поняв происходящего, я тупо сейвил текст и обратил внимание, что на iPad в такт моим сейвам сверху на мгновение показывается нативный анимированный лоадер (или как оно называется, иконка загрузки короче).
Ага! Вот ты и попался. Видимо, браузер слишком рано хочет сделать себя LiveForever. Надо ему подпилить чего-нибудь…

Полез в исходники reload-а в /node_modules/reload/lib/ (как я сразу не додумался, стыд-позор мне), и нарыл там 4 файла:
reload.js, reload-client.js, reload-server.js, sockjs-0.3-min.js.
Сразу же заинтересовал reload-client.js, смотрим, и в самом начале файла, прям во второй строчке, находим решение всех проблем человечества:
;(function refresh () {
  var RLD_TIMEOUT = 300;
  var sock = new SockJS(window.location.origin + '/sockreload');

  sock.onclose = function() {
    setTimeout(function() {
      window.location.reload();
    },RLD_TIMEOUT);
  };
})();


Подытожим, господа!


Опытным путем, сделать бесфейловый LiveReload мне помогло минимальное значение RLD_TIMEOUT = 700;

На этом всё. Полученным решением я доволен, всё работает так, как мне, далекому от веб-разработки и веб-магий человеку, и нужно было — легко и непринужденно, главное — без заморочек и уговоров жаб.
Tags:
Hubs:
+4
Comments 1
Comments Comments 1

Articles