Технический долг — вещь, знакомая многим компаниям и программистам. Обычно он копится годами, чтобы потом, подобно сизифову камню, держать в тонусе всех и вся. Под катом — рассказ Альберта Халимова, одного из членов команды «М.Видео – Эльдорадо», о том, как мы справляемся с подобными недугами.

Привет, Хабр!

Расскажу, как мы спасли проект с фронтендом, который изначально разрабатывался внешними подрядчиками, а нам достался уже в тяжёлом состоянии: с устаревшими технологиями, отсутствием единого стиля и внушительным техническим долгом. Тем не менее, нам удалось не только стабилизировать разработку, но и провести полноценную модернизацию — по всем фронтам: от сборки и зависимостей до архитектуры и инфраструктуры.

Вот что мы имели на входе:

  • Vue 2, Vuex 3, vue-cli, Node.js 16 

  • Папка dist: 22.4 MB 

  • Время сборки: 90 секунд 

Два чанка на весь проект: app.js — 550 KiB, vendor.js — 1330 KiB

На выходе получили:

  • Vue 3, Pinia, Vite, Composition API, TypeScript 

  • Папка dist: 3.5 MB 

  • Время сборки: 20 секунд 

  • Скорость загрузки страниц выросла на 15–25% 

И всё это без заморозки разработки новых фич.

Первый звоночек

Первое, что бросилось в глаза — это размер dist и всего два чанка. Команда сборки выглядела так:

Выглядело странно. На деле, вес проекта был почти в два раза меньше — ~11.2 MB. Просто дублировали dist. Понял, что структура сборки вообще не продумывалась — просто как-нибудь, лишь бы билдилось. Удивлён не был. Но понял: впереди много работы.

С чего начал: аудит и приоритизация

Перед тем как лечить, я провёл первичный аудит кода:

  1. Повторяющийся код — форматирование, даты, маски и прочее.

  2. Зависимости-дубли — в одном проекте были и v-mask, и imask, и vue-imask, и vue-input-mask. Аналогично с v-tooltip, vuetify, tooltip.js.

  3. Костыли и антипаттерны — логика, которую не могли объяснить даже авторы.

  4. Список ТехДолга — отдельный документ, жёсткая декомпозиция по категориям: сборка, архитектура, дизайн-система, хранилище, UI-библиотеки и т.д.

Мы не делали рефакторинг в ветках с фичами. Только отдельные MR. Это защищало нас от сбоев, позволило нормально тестировать и не тормозить разработку новых функций.

Оптимизация зависимостей

Первым делом я избавился от «братских» библиотек. Выбрал один пакет на каждую задачу — тот, который поддерживает Vue 3 и активно развивается. В идеале — на TypeScript.

Дальше:

  • Все утилитарные функции были вынесены в utils

  • Начал вводить линтер и автоформаттер поэтапно: сначала ESLint с мягкими правилами, затем Prettier, затем husky с pre-commit хуками

  • Наращивал строгость линтера, переводил предупреждения в ошибки

Через месяц почти весь фронт стал единообразным. И только после этого мы начали миграцию на Vite.

Переезд на Vite

Миграция прошла безболезненно — если не считать один нюанс. При переходе с process.env на import.meta.env я не заметил кусок:

В итоге потеряли данные аналитики за две недели. Да, бывает. Обжёгся — теперь в такие моменты захожу с grep и ищу по проекту вручную все process.env.

Зато после переезда:

  • Время сборки сократилось до 30 секунд 

  • После замены sass на sass-embedded, минификации всех SVG и кастомизации Vite-конфига — до 20 секунд 

  • Вес dist стал 5.7 MB, а после перехода на Vue 3 и чистки ненужного — 3.5 MB 

Плавный переход на Vue 3, Pinia и TypeScript

Здесь стратегия была максимально аккуратной:

  • Все новые модули писались на Composition API и TypeScript 

  • Pinia существовал параллельно с Vuex

  • Миграция шла по частям: сначала простые модули, потом отдельные компоненты, только в конце — запутанные сущности с side effects

Так мы не тормозили разработку и не тратили месяцы на «глобальный рефакторинг, который никто не увидит».

Ещё пара мелочей, которые сэкономили часы

  • Прописал конкретную версию yarn в package.json — CI начал стартовать быстрее на 1.5–2 минуты

  • Автоматизировал прогон линтера и форматтера — минус тонны мусора в MR'ах

Выводы

Самый важный инсайт — не надо бояться технического долга. Надо просто системно с ним работать. В этом кейсе удалось:

  • Провести аудит и зафиксировать конкретные участки проблем

  • Встроить решение в текущие процессы, не нарушая поставку новых фич

  • Поэтапно провести миграции, не ломая ничего и не вводя хаос

Итоги в цифрах:

Показатель

Было

Стало

Вес dist

22.4 MB

3.5 MB

Время сборки

90 сек

20 сек

Скорость загрузки

+15–25%

Спасибо за внимание. Пишите в комментариях о своем опыте работы с техдолгом.

P.S. Хорошие материалы по заявленной теме можно найти также здесь, здесь и здесь.

Комментарии (0)