← Назад к вопросам

Как работаешь с кодом с костылями?

2.0 Middle🔥 171 комментариев
#Soft Skills и рабочие процессы

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Работа с техническим долгом

Кажда разработчик рано или поздно сталкивается с кодом, содержащим "костыли" (workarounds, хаки, временные решения). Правильное управление таким кодом критично для поддержки проекта и команды. Мой подход систематический и ориентирован на долгосрочную стабильность.

Шаг 1: Оценка и документирование

Перво-наперво нужно понять, что перед тобой:

// ❌ Костыль без комментария
if (userAgent.includes('Safari')) {
  element.style.width = '99%'; // Магическое число
}

// ✅ Документированный костыль
// HACK: Safari 15 имеет баг с width: 100% в flex контексте
// Issue: https://bugs.webkit.org/show_bug.cgi?id=123456
// TODO: Удалить когда Safari >= 16 будет минимальной версией
if (userAgent.includes('Safari')) {
  element.style.width = '99%';
}

Документирование важно, потому что:

  • Помогает будущим разработчикам (или тебе через полгода) понять, почему это было необходимо
  • Указывает версии браузеров или библиотек, где был баг
  • Показывает ссылку на issue или PR для отслеживания

Шаг 2: Создание Issue и отслеживание

Для каждого костыля создаю Issue с меткой "technical-debt":

Заголовок: [TECH DEBT] Удалить костыль для Safari flex width

Описание:
- Текущее решение: 99% ширина вместо 100%
- Причина: баг в Safari 15
- Можно удалить: когда будет поддержка только Safari 16+
- Файл: /src/components/Modal.tsx:45
- Обсуждение: https://bugs.webkit.org/...

Это позволяет:

  • Отслеживать все костыли в одном месте
  • Периодически проверять, можно ли их удалить
  • Планировать рефакторинг в спринтах

Шаг 3: Минимизация влияния

Если нужно работать с существующим костылем, стараюсь ограничить его влияние:

// ❌ Плохо: костыль загрязняет весь компонент
function Modal() {
  if (browser.isSafari) {
    // специальная логика
  }
  if (browser.isIE) {
    // еще специальная логика
  }
  // основной код
}

// ✅ Хорошо: костыль изолирован в отдельном хуке
function useWorkaroundSafariWidth() {
  const ref = useRef(null);
  
  useEffect(() => {
    if (ref.current && isSafariBelow16()) {
      ref.current.style.width = '99%';
    }
  }, []);
  
  return ref;
}

function Modal() {
  const safariRef = useWorkaroundSafariWidth();
  return <div ref={safariRef}>...</div>;
}

Шаг 4: Прогрессивное улучшение

Если костыль сложный, разбиваю рефакторинг на части:

// Фаза 1: Изолирование
// Выношу костыль в отдельный файл/модуль

// Фаза 2: Тестирование
// Добавляю тесты для текущего поведения
// Убеждаюсь, что костыль работает как ожидается

// Фаза 3: Подготовка замены
// Пишу новый код, который работает без костыля
// Запускаю оба варианта параллельно

// Фаза 4: Миграция
// Постепенно переходим на новый код
// Удаляем старый костыль

Шаг 5: Коммуникация в команде

Обсуждаю костыли на code review и ретроспективах:

В PR comment:
"Я вижу здесь костыль для IE11 (строка 42). Он документирован 
и отслеживается в issue #1234. Планируем удалить в спринте N, 
когда поддержка IE11 будет прекращена."

Это помогает:

  • Предотвратить дублирование костылей
  • Объединить усилия команды
  • Планировать удаление

Пример реальной ситуации

// Костыль: Firefox не поддерживает CSS mask-image с SVG
function getBackgroundImage(svgUrl: string) {
  const isFirefox = navigator.userAgent.includes('Firefox');
  
  if (isFirefox) {
    // WORKAROUND: Firefox баг #1234567
    // CSS mask-image не работает с внешними SVG
    // Используем встроенный SVG вместо ссылки
    return `url('data:image/svg+xml;utf8,<svg>...</svg>')`;
  }
  
  return `url('${svgUrl}')`;
}

Когда Firefox выпустит фикс:

// Обновляем функцию
function getBackgroundImage(svgUrl: string) {
  // Костыль удален - Firefox теперь поддерживает CSS mask-image
  return `url('${svgUrl}')`;
}

Вредные практики, которых избегаю

// ❌ Не делаю так:
// 1. Оставляю костыли без документации
// 2. Не отслеживаю их
// 3. Дублирую один костыль в разных местах
// 4. Забываю про них навсегда
// 5. Добавляю все новые костыли вместо рефакторинга

Системный подход

  1. Каждый костыль должен быть задокументирован - комментарий с причиной
  2. Каждый костыль должен быть отслежен - issue или TODO
  3. Костыли должны быть минимизированы - не должны загрязнять основной код
  4. Регулярно проверяю - можно ли удалить, когда поддержка изменилась
  5. Планирую рефакторинг - включаю в спринты удаление техдолга

Итог

Костыли иногда необходимы для решения срочных проблем. Но их нужно рассматривать как временные решения, а не постоянные. Правильная документация, изоляция, отслеживание и планомерное удаление - ключ к поддерживаемому коду. Это показывает профессионализм и заботу о качестве проекта.