#заметка дня
Сказ о том, как я Hot Module Reload в секьюрном iframe настраивал. Итак, если вы на канале достаточно давно, то можете вспомнить, что продукт, над которым я работаю — это расширение для Google Sheets и работает оно в iframe. Довольно таки огороженном iframe.
Ну как, огороженном... Там довольно странная система из четырёх вложенных iframe, каждый из которых имеет довольно жёсткие скоупы.
И в итоге, такая простая вещь как Live Reload оказалась мне попросту недоступна!
Можете себе представить, как задалбывало перезапускать проект каждый раз, когда я что-то менял? А перезапуск — это секунд 10-15, даже если сборка почти моментальная.
Любая попытка сделать window.location.reload() не то чтобы по команде из Live Server-решения, но даже по кнопке — приводила к краху iframe и, соответственно, продукта.
Оставался только один вариант — Hot Module Replacement. Да, горячая перезагрузка компонентов с нами уже несколько лет, но для легаси-проектов это достаточно проблематично. И хоть я уже 2 года как перелез на
https://rspack.dev/ (и дико доволен), использовать на полную катушку не выходило.
Как я справлялся?А я запускал куски продукта в песочницах. Набрасывал моки и запускал блоки компонентов как обычное SPA-приложение. Не очень удобно? Не то слово. Зато очень быстро и легко покрывается тестами — потому что все моки уже на месте.
Сплошные плюсы.
Но при работе в команде это всё максимально неудобно. В итоге всё же пришлось разбираться с HMR.
Итак, в чём же сложности?
1. Для начала, в Google Sheets нужно передать адрес, по которому будут грузиться данные. Нет, просто localhost нельзя, нужно сохранять возможность поделиться dev-средой, как обычной таблицей.
Решение — туннели (вроде ngrok) с прокидыванием локального домена (try_files в nginx) прямо к файлам сборки.
2. Естественно, данные должны грузиться по https. К счастью, туннели и это решают.
3. Не всем разработчикам в компании нужен HMR, им достаточно и простой сборки.
4. А вот что туннели решали с трудом — это прокидывание WebSocket. Именно по ним сборка и узнаёт, что пришло время обновиться. Я никак не мог понять, как же правильно поднять одновременно https и туннель, чтобы браузер не ругался на несекьюрный источник.
И тут до меня дошло: localhost же у нас по-соглашению всегда секьюрный. Поднимать на нём https не только не имеет смысла, но и браузерам абсолютно всё равно не несекьюрные данные оттуда!
Но был нюанс: если прописать localhost в конфиге webpack-dev-server (а Rspack использует именно его), то он просто... исчезал. Растворялся в basePath, указывая на текущую страницу (aka источник iframe). Что, конечно, меня не устраивало.
К счастью, решилось старым добрым
127.0.0.1.
В остальном же проблем не возникло: HMR прекрасно настроился по
официальной документации с
React Fast Refresh и получился следующий конфиг:
1. Три режима среды сборки: dev, none и production. Под none подразумевается дев-билд, без запуска сервера.
2. Туннели прокинуты до каталога build внутри репозитория и предоставляют доступ из
открытого интернета по кастомному домену, с https на http.
3. webpack-dev-server настроен таким образом, что чанки с обновлениями сохраняются на диск и таким способом доставляются по адресу этого же тоннеля. Формат имён одинаков для сред dev и none.
4. CORS отключён ('Access-Control-Allow-Origin': '*'),
и это пока мне не очень нравится.
5. WebSocket-соединение просто запущено на
127.0.0.1.
Таким образом, получился отличный универсальный способ!
Все разработчики компании без необходимости в HMR могут просто запустить локальный билд. А те, кому надо — запускают
yarn dev и больше никакой дополнительной конфигурации не требуется.
А главное, за счёт скорости работы Rspack я могу смело указать несколько точек входа (entrypoints) и запускать независимые друг от друга части продукта с сохранением горячей перезагрузки.
Да, немного сумбурно вышло, и большинству такое в жизни не пригодится. Но если вдруг у вас возникнет такая же необходимость шарить dev-среду проекта наружу в открытую сеть — вы знаете, что делать.
#rspack #webpack #hmr