2026-09-22
Баги, которые живут только в production
Я делаю этот сайт открыто. Один монорепозиторий, Fastify рендерит React, рядом небольшое API на Hono, а всё это живёт в k3s на одной ARM-машине.
Локально проект тоже работает в Docker с примонтированным исходным кодом, поэтому в контейнерах крутится ровно то, что я только что написал.
Но на этой неделе два бага существовали только в production-сборке. Как раз хороший повод про них рассказать.
Padding, который исчезал
У каждой страницы свои отступы:
padding: 96px 24px 120px
А общий .container задавал:
padding: 0 24px
Специфичность одинаковая, поэтому побеждает правило, которое браузер увидел последним.
В development последним оказывался стиль страницы, и всё выглядело нормально. В production порядок
менялся, побеждал .container, верхний отступ становился нулевым, а текст уезжал под фиксированную шапку.
Починка — буквально одно слово: padding-inline.
Он отвечает только за боковые отступы и не трогает верхний и нижний, поэтому порядок правил больше ничего не решает.
Переводы, которых не было
В production SSR-плагин импортирует серверный бандл ещё при регистрации в Fastify — до того, как сервер начал слушать порт.
А мой entry запускал i18next.init() прямо во время импорта. Локали i18next загружал по HTTP с этого же
сервера, который в этот момент ещё не был доступен.
Запрос падал, ошибка оставалась в состоянии i18next, и дальше SSR отдавал вместо переводов ключи вроде
stack_lead.
В development этого не происходило: Vite загружал entry уже при первом запросе, когда сервер был запущен.
Я перенёс инициализацию i18next на первый рендер. А initImmediate: false закрыл ещё одну гонку: теперь
init() не заканчивается раньше, чем локали действительно оказываются в store.
Что у них общего
Оба бага про одно и то же: development и production — не совсем одна и та же программа.
Меняется порядок файлов, момент загрузки модулей и последовательность старта. Тесты этого не поймали. Я тоже не поймал, пока не собрал настоящий production-образ и не открыл его как обычный пользователь.
Поэтому production-стек у меня поднимается одной командой. И прежде чем считать что-то рабочим, я стараюсь хотя бы один раз посмотреть на него именно там.