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

в 9:48, , рубрики: javascript, livereload, node.js, практические советы, метки: , , ,

Заморочился я автообновлением странички в браузере на таскаемом с собой 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;

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

Автор: beaverBox

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js