Получение stats и обработка ошибок программно

Компиляция Webpack в программном режиме через Node.js API позволяет получить полный контроль над процессом сборки, включая доступ к статистике (stats) и перехват ошибок без участия CLI. Это особенно важно при интеграции сборки в серверные приложения, CI/CD пайплайны, кастомные инструменты разработки и SSR-сценарии.


Webpack может быть вызван как обычная функция, принимающая конфигурацию. В этом случае результатом работы становится объект компиляции, содержащий подробную информацию о процессе сборки.

const webpack = require('webpack');
const config = require('./webpack.config');

webpack(config, (err, stats) => {
  // обработка результата сборки
});

Callback принимает два аргумента:

  • err — критическая ошибка самого процесса запуска (не ошибки кода проекта)
  • stats — объект статистики компиляции

Разделение ошибок: системные и компиляционные

В Webpack важно различать два уровня ошибок:

Системные ошибки (fatal errors)

Это ошибки, которые возникают до начала или во время инициализации компиляции:

  • неверный конфиг Webpack
  • отсутствие зависимостей
  • ошибки Node.js окружения
  • сбои плагинов на этапе инициализации

Такие ошибки передаются через err:

webpack(config, (err, stats) => {
  if (err) {
    console.error('Fatal Webpack error:', err);
    return;
  }
});

Ошибки компиляции (compilation errors)

Это ошибки, возникающие при обработке исходного кода:

  • синтаксические ошибки JavaScript/TypeScript
  • ошибки загрузчиков (loaders)
  • ошибки плагинов на этапе сборки модулей

Они находятся внутри stats:


Объект stats и его структура

Объект stats — это основной источник информации о сборке. Он содержит:

  • список модулей
  • ошибки и предупреждения
  • информацию о чанках
  • время сборки
  • размеры бандлов

Для удобного использования Webpack предоставляет метод toJson():

webpack(config, (err, stats) => {
  if (err) {
    console.error(err);
    return;
  }

  const info = stats.toJson();
});

Извлечение ошибок из stats

Ошибки компиляции находятся в поле errors:

webpack(config, (err, stats) => {
  if (err) return;

  const info = stats.toJson();

  if (info.errors && info.errors.length > 0) {
    console.log('Compilation errors:');

    info.errors.forEach(error => {
      console.log(error.message || error);
    });
  }
});

Ошибки могут быть:

  • строками
  • объектами с полями message, moduleName, loc
  • форматированными сообщениями loader’ов

Предупреждения (warnings)

Предупреждения не прерывают сборку, но часто указывают на потенциальные проблемы:

if (info.warnings && info.warnings.length > 0) {
  info.warnings.forEach(warning => {
    console.warn(warning.message || warning);
  });
}

Типичные причины warnings:

  • неиспользуемые экспорты
  • устаревшие API
  • конфликты chunk splitting
  • fallback поведения loaders

Форматирование stats для вывода

Webpack позволяет управлять уровнем детализации через опции stats:

const config = {
  stats: {
    all: false,
    errors: true,
    warnings: true,
    errorDetails: true,
    colors: true
  }
};

Основные параметры:

  • all — включает/выключает всё
  • errors — отображение ошибок
  • warnings — отображение предупреждений
  • errorDetails — расширенная информация (stack trace, location)
  • colors — цветной вывод

Программная фильтрация ошибок

В реальных системах важно не просто вывести ошибки, а классифицировать их.

Пример базовой фильтрации

function processStats(stats) {
  const info = stats.toJson({ all: false, errors: true, warnings: true });

  const errors = info.errors || [];
  const warnings = info.warnings || [];

  const formatted = {
    hasErrors: errors.length > 0,
    hasWarnings: warnings.length > 0,
    errors,
    warnings
  };

  return formatted;
}

Генерация исключения при ошибках сборки

В CI/CD сценариях часто требуется прерывать процесс при наличии ошибок:

webpack(config, (err, stats) => {
  if (err) {
    throw err;
  }

  const info = stats.toJson();

  if (info.errors && info.errors.length > 0) {
    throw new Error(
      'Webpack compilation failed:\n' +
      info.errors.map(e => e.message || e).join('\n')
    );
  }
});

Такой подход гарантирует, что пайплайн завершится с ошибкой.


Использование stats в watch-режиме

При использовании watch Webpack вызывает callback при каждом изменении файлов.

const compiler = webpack(config);

compiler.watch({}, (err, stats) => {
  if (err) {
    console.error(err);
    return;
  }

  const info = stats.toJson();

  if (info.errors.length) {
    console.log('Errors in watch build');
  }
});

Особенность watch-режима:

  • сборка происходит многократно
  • stats всегда отражает последнюю компиляцию
  • ошибки могут появляться и исчезать между итерациями

Отладка через расширенный stats

Для глубокого анализа можно включить детализированный вывод модулей:

const info = stats.toJson({
  all: false,
  modules: true,
  reasons: true,
  source: false
});

Полезные поля:

  • modules — список всех модулей сборки
  • reasons — причины включения модуля в бандл
  • source — исходный код (использовать осторожно из-за объема)

Интеграция stats в собственные системы логирования

Webpack stats часто используется для построения кастомных логгеров:

function logStats(stats) {
  const info = stats.toJson({ errors: true, warnings: true });

  const timestamp = new Date().toISOString();

  if (info.errors.length) {
    console.log(`[${timestamp}] ERRORS:`);
    info.errors.forEach(e => console.log(e.message || e));
  }

  if (info.warnings.length) {
    console.log(`[${timestamp}] WARNINGS:`);
    info.warnings.forEach(w => console.log(w.message || w));
  }
}

Такие логгеры используются:

  • в build-серверах
  • в Docker контейнерах
  • в системах мониторинга сборки

Асинхронная обработка через Promise API

Webpack поддерживает использование Promise-обертки для более удобной обработки ошибок:

const compiler = webpack(config);

compiler.run((err, stats) => {
  if (err) throw err;

  const info = stats.toJson();

  if (info.errors.length) {
    throw new Error(info.errors.join('\n'));
  }
});

В современных архитектурах часто используется обертка:

function runWebpack(config) {
  return new Promise((resolve, reject) => {
    webpack(config, (err, stats) => {
      if (err) return reject(err);

      const info = stats.toJson();

      if (info.errors.length) {
        return reject(new Error('Build failed'));
      }

      resolve(stats);
    });
  });
}

Особенности сериализации stats

Объект stats содержит сложные структуры, которые:

  • не предназначены для прямой JSON-сериализации
  • могут включать циклические зависимости
  • требуют использования toJson()

Попытка прямого JSON.stringify(stats) приводит к ошибкам или потере данных.


Производственные рекомендации обработки ошибок

При работе в реальных проектах обычно применяется следующая логика:

  • err → мгновенная остановка процесса
  • stats.errors → ошибка сборки (fail build)
  • stats.warnings → логирование без остановки
  • успешный stats → анализ и публикация артефактов

Эта модель обеспечивает предсказуемое поведение сборочной системы и позволяет интегрировать Webpack в сложные автоматизированные пайплайны без потери контроля над состоянием сборки.