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

Как дебажишь код?

1.0 Junior🔥 161 комментариев
#JavaScript Core

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

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

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

Методы отладки (Debugging) в Frontend разработке

Отладка - это один из самых важных навыков, который отделяет опытных разработчиков от новичков. Моя методология эволюционировала с годами, и сейчас я использую комбинацию инструментов и подходов в зависимости от проблемы.

Подход 1: Browser DevTools (основной инструмент)

1. Chrome/Edge DevTools - Console tab

Первое что я делаю при ошибке:

// Просто выводить значения
console.log('User:', user);

// Использовать различные методы console
console.error('Error message', error); // красное сообщение
console.warn('Warning', warning); // жёлтое
console.info('Info message'); // синее
console.table(arrayOfObjects); // таблица

// Условное логирование
const DEBUG = process.env.NODE_ENV === 'development';
DEBUG && console.log('Debug info');

// Группировка логов
console.group('User Data');
console.log('ID:', user.id);
console.log('Name:', user.name);
console.groupEnd();

// Таймеры
console.time('api-request');
fetch('/api/users')
  .finally(() => console.timeEnd('api-request'));

// Счётчики
console.count('render'); // выведет 'render: 1', 'render: 2', etc

2. Chrome DevTools - Sources tab (Breakpoints)

Это мощный инструмент для пошагового выполнения кода:

// Установка точки останова
// 1. Открыть Sources tab
// 2. Найти файл
// 3. Кликнуть на номер строки
// 4. Код остановится когда достигнет этой строки

function calculateTotal(items) {
  // Установи breakpoint здесь
  let total = 0;
  for (let item of items) {
    total += item.price; // breakpoint: смотри значение total
  }
  return total;
}

// Условные breakpoints
// Правый клик на breakpoint -> Add conditional breakpoint
// Условие: item.price > 1000 (остановится только если условие true)

Функции при breakpoint:

  • Step over (F10) - выполнить текущую строку
  • Step into (F11) - войти в функцию
  • Step out (Shift+F11) - выйти из функции
  • Continue (F8) - продолжить до следующего breakpoint
  • Watch - смотреть значения переменных в реальном времени
  • Call Stack - видеть стек вызовов
// Watch expressions
// Добавить в Watch: user.name, total > 100, items.length
// Будут обновляться при каждом шаге

3. Chrome DevTools - Elements tab

Для отладки DOM и стилей:

// Инспектируй элементы
// 1. Правый клик на элемент -> Inspect
// 2. Видишь HTML и все стили
// 3. Можешь менять CSS в реальном времени

// Полезное - показать все event listeners
// Элемент -> Event Listeners panel
// Видишь все обработчики на элементе

// Отладка хидден элементов
// Консоль: document.querySelectorAll('.hidden')
// Правый клик -> Inspect -> видишь почему скрыт

4. Chrome DevTools - Network tab

Для отладки API запросов:

// Смотреть все HTTP запросы
// Network tab -> видишь все запросы, ответы, время

// Фильтрация запросов
// Фильтр по типу: XHR, Fetch, Img, etc

// Проверка ответа
// Клик на запрос -> Response tab -> видишь JSON

// Проверка headers
// Headers tab -> видишь Authorization, Content-Type, etc

// Replay запроса
// Правый клик на запрос -> Replay XHR
// Полезно для воспроизведения проблемы

// Slow network simulation
// Network tab -> Throttling dropdown -> Slow 3G
// Тестируешь как работает на медленном интернете

Подход 2: Console API для custom отладки

Добавляю специальные функции для отладки:

// utils/debug.ts
const DEBUG_MODE = process.env.NODE_ENV === 'development';

export function debugLog(label: string, data: any) {
  if (!DEBUG_MODE) return;
  console.log(`[${label}]`, data);
}

export function debugError(label: string, error: any) {
  if (!DEBUG_MODE) return;
  console.error(`[ERROR - ${label}]`, error);
  // Также можно отправить в error tracking service
  // captureException(error, { tags: { label } });
}

export function debugPerformance(label: string) {
  if (!DEBUG_MODE) return;
  console.time(label);
  return () => console.timeEnd(label);
}

// Использование
debugLog('User loaded', user);
const endTimer = debugPerformance('API request');
await fetch('/api/users');
endTimer();

Подход 3: React-specific отладка

React DevTools Browser Extension

// 1. Установи React DevTools расширение
// 2. Открой DevTools -> Components tab
// 3. Видишь component tree
// 4. Клик на component -> видишь props и state

// Отладка ре-рендеров
// DevTools -> Profiler tab
// Видишь какие компоненты ре-рендерятся и почему
// Ищешь unnecessary re-renders

// Отладка hooks
// Клик на component -> видишь все hooks и их значения

Отладка в коде React

import { useEffect } from 'react';

function UserProfile({ userId }) {
  // Логирование props изменений
  useEffect(() => {
    console.log('userId changed to:', userId);
  }, [userId]);

  // Логирование ре-рендеров
  useEffect(() => {
    console.log('Component rendered');
  });

  // Отладка state изменений
  const [user, setUser] = useState(null);
  useEffect(() => {
    console.log('User state:', user);
  }, [user]);

  // Отладка useEffect зависимостей
  useEffect(() => {
    console.log('Effect dependencies changed');
    // ESLint warning если забыл зависимость
  }, [userId, user]);
}

Подход 4: Network и API отладка

Перехватывание запросов

// utils/api.ts
import axios, { AxiosInstance } from 'axios';

const api: AxiosInstance = axios.create({
  baseURL: process.env.REACT_APP_API_URL
});

// Логирование всех запросов
api.interceptors.request.use((config) => {
  console.log('[API REQUEST]', config.method?.toUpperCase(), config.url);
  console.log('Headers:', config.headers);
  console.log('Data:', config.data);
  return config;
});

// Логирование всех ответов
api.interceptors.response.use(
  (response) => {
    console.log('[API RESPONSE]', response.status, response.data);
    return response;
  },
  (error) => {
    console.error('[API ERROR]', error.response?.status, error.message);
    return Promise.reject(error);
  }
);

export default api;

Mock API для тестирования

// Использую MSW (Mock Service Worker) для интерцепции запросов
import { setupServer } from 'msw/node';
import { rest } from 'msw';

const server = setupServer(
  rest.get('/api/users/:id', (req, res, ctx) => {
    console.log('[MOCK] GET /api/users/:id');
    return res(
      ctx.status(200),
      ctx.json({
        id: req.params.id,
        name: 'Test User'
      })
    );
  })
);

server.listen();

Подход 5: Performance Profiling

Измерение производительности

// 1. Chrome DevTools -> Performance tab
// 2. Нажми Record
// 3. Выполни действие
// 4. Stop recording
// 5. Видишь timeline с длительностью каждого действия

// Programmatic performance measurement
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration}ms`);
  });
});

observer.observe({ entryTypes: ['measure', 'navigation'] });

// Manually measuring
performance.mark('start');
// ... do something
performance.mark('end');
performance.measure('my-operation', 'start', 'end');

// Web Vitals
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

getLCP(console.log); // Largest Contentful Paint
getFID(console.log); // First Input Delay
getCLS(console.log); // Cumulative Layout Shift

Подход 6: Error Handling и Error Tracking

Global error catching

// Ловить необработанные ошибки
window.addEventListener('error', (event) => {
  console.error('Uncaught error:', event.error);
  // Отправить в error tracking (Sentry, Rollbar, etc)
  reportError(event.error);
});

// Ловить Promise rejections
window.addEventListener('unhandledrejection', (event) => {
  console.error('Unhandled rejection:', event.reason);
  reportError(event.reason);
});

// React Error Boundary
class ErrorBoundary extends React.Component {
  componentDidCatch(error, errorInfo) {
    console.error('React Error:', error);
    // Отправить в error tracking
    reportError(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <div>Something went wrong</div>;
    }
    return this.props.children;
  }
}

Error tracking service

// Используя Sentry
import * as Sentry from '@sentry/react';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 1.0,
});

// Автоматически ловит все ошибки
// Можешь вручную отправить
Sentry.captureException(error);
Sentry.captureMessage('Custom message');

Подход 7: Source Maps и Original Code

Отладка compiled / minified кода

// Включи source maps в конфиге
// webpack.config.js
module.exports = {
  devtool: 'source-map', // development
  // или
  devtool: 'hidden-source-map', // production (скрыто от пользователя)
};

// Теперь в DevTools видишь оригинальный код
// Вместо minified версии

Подход 8: Отладка in Production

Для issues в production используем:

// 1. Browser console в production (если нужно)
// Может быть скрыто от пользователя
if (process.env.REACT_APP_DEBUG_MODE === 'true') {
  window.__DEBUG__ = true;
}

// 2. Remote debugging
// Используя LogRocket, Sentry с session replay

// 3. User feedback
const reportIssue = () => {
  const userData = {
    userAgent: navigator.userAgent,
    url: window.location.href,
    timestamp: new Date().toISOString()
  };
  // Отправить feedback в систему
};

Мой typical debugging flow

  1. Шаг 1: Воспроизведение

    • Открываю issue
    • Пытаюсь повторить проблему
    • Смотрю консоль -> есть ли ошибки
  2. Шаг 2: Поиск источника

    • Network tab -> все ли запросы успешны
    • Elements tab -> правильный ли HTML/CSS
    • Console -> есть ли JavaScript ошибки
  3. Шаг 3: Локализация

    • Использую console.log для сужения области поиска
    • React DevTools для проверки props/state
    • Breakpoints если нужны более точные данные
  4. Шаг 4: Фикс

    • Понимаю корневую причину
    • Пишу тест который проверяет проблему
    • Фиксю код
  5. Шаг 5: Проверка

    • Повторяю шаги для воспроизведения
    • Проверяю related функционал
    • Смотрю не сломал ли что ещё

Best practices отладки

// ✅ Хорошо
// Структурированное логирование
const debugInfo = {
  timestamp: new Date(),
  userId: user?.id,
  action: 'login',
  status: 'success'
};
console.log('[AUTH]', debugInfo);

// ❌ Плохо
// Непонятные логи
console.log('x:', x); // что это x?
console.log('asdf'); // почему асдф?

// ✅ Хорошо
// Временная отладка с удалением потом
if (process.env.NODE_ENV === 'development') {
  console.log('Debug:', data);
}

// ❌ Плохо
// Оставить console.log в production коде
console.log('DEBUG:', something); // заспамит консоль

Итог

Моя методология отладки:

  1. Начинаю с Console - быстро понять что происходит
  2. Использую Browser DevTools - Sources для breakpoints, Network для API
  3. React DevTools - для component-specific проблем
  4. Profiler - если проблема в performance
  5. Error tracking - для production issues
  6. Тесты - чтобы не сломать снова

Отладка - это навык, который улучшается с опытом. Чем больше ошибок видишь, тем быстрее научишься их находить и исправлять.