Как происходит выкатывание в продакшн?
Что проверяют
Понимаете ли вы путь кода от мёржа до браузера пользователя и что делать, когда релиз сломался. Следом обычно спрашивают, как откатиться за минуту и почему после деплоя у части пользователей «белый экран».
Как отвечать
Опишите по шагам конвейер, с которым работали:
- CI на каждый merge request: линтер, проверка типов через
tsc --noEmit, юнит-тесты на Vitest или Jest, сборка. Красное не мёржится; - артефакт: Vite или webpack выдают статику с хэшем в имени файла (
app.3f9a1c.js). Собирать лучше один раз и продвигать тот же артефакт по стендам; - стенды: dev, stage, прод. На stage прогоняются e2e на Playwright или Cypress;
- выкладка: статика уезжает в объектное хранилище за CDN, в контейнер с nginx или на платформу вроде Vercel. SSR-приложение на Next.js или Nuxt выкатывается как Node-сервис;
- кеширование: файлы с хэшем отдаются с
Cache-Control: public, max-age=31536000, immutable, аindex.htmlсno-cache, чтобы браузер всегда узнавал о новой версии; - снижение риска: canary на часть трафика, blue-green, фичефлаги, чтобы выкатить код выключенным;
- наблюдение: ошибки в Sentry с загруженными source maps, метрики Web Vitals, всплеск ошибок после релиза виден сразу.
Откат во фронтенде простой, если прошлый артефакт сохранён: переключаете указатель на предыдущую сборку или перевыкатываете её без новой сборки.
Где спотыкаются
Кешируют index.html надолго. Пользователь неделю видит старую версию, а после чистки кеша часть чанков уже не находится.
Удаляют старые чанки сразу после деплоя. Открытая вкладка со старой версией при переходе запросит несуществующий файл и получит ChunkLoadError, поэтому старые ассеты держат хотя бы несколько дней.
Забывают, что переменные вроде VITE_* и NEXT_PUBLIC_* вшиваются в бандл при сборке. Поменять их на сервере без пересборки нельзя, и один артефакт на все стенды тогда требует конфига, который читается в рантайме.