Передача опций загрузчику

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

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


Основной способ передачи: объект options в конфигурации rules

Современный стандарт Webpack предполагает передачу параметров через поле options внутри правила module.rules.

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: [
          {
            loader: 'custom-loader',
            options: {
              prefix: 'DEBUG:',
              encoding: 'utf8'
            }
          }
        ]
      }
    ]
  }
}

Внутри загрузчика эти параметры доступны через объект this.query (в старых версиях) или через аргумент options, получаемый через API loader-utils или this.getOptions() в актуальных версиях Webpack.


Современный доступ к опциям через this.getOptions()

В актуальной архитектуре загрузчиков Webpack рекомендуется использовать this.getOptions().

module.exports = function (source) {
  const options = this.getOptions();

  const prefix = options.prefix || '';

  return prefix + source;
};

Такой подход заменяет устаревшие механизмы и обеспечивает корректную работу с JSON Schema валидацией опций.


Передача параметров через query-строку (устаревший механизм)

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

module: {
  rules: [
    {
      test: /\.txt$/,
      use: 'custom-loader?prefix=DEBUG&encoding=utf8'
    }
  ]
}

Внутри загрузчика доступ к параметрам осуществлялся через this.query:

module.exports = function (source) {
  const query = this.query;

  return query.prefix + source;
};

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


Использование loader-utils для обработки параметров

До появления встроенного метода this.getOptions() широко использовалась библиотека loader-utils.

const { getOptions } = require('loader-utils');

module.exports = function (source) {
  const options = getOptions(this);

  return options.prefix + source;
};

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


Передача опций при цепочке загрузчиков

При использовании нескольких загрузчиков порядок выполнения влияет на контекст передачи данных, однако опции каждого загрузчика изолированы.

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: [
          {
            loader: 'first-loader',
            options: { stage: 1 }
          },
          {
            loader: 'second-loader',
            options: { stage: 2 }
          }
        ]
      }
    ]
  }
}

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


Валидация опций через schema

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

module.exports = function (source) {
  const options = this.getOptions();

  return source;
};

module.exports.raw = false;

module.exports.schema = {
  type: 'object',
  properties: {
    prefix: {
      type: 'string'
    },
    encoding: {
      type: 'string'
    }
  },
  additionalProperties: false
};

При несовпадении структуры конфигурации сборка завершается с ошибкой валидации.


Контекст выполнения и доступ к опциям

Загрузчик вызывается в рамках специального контекста, предоставляемого Webpack. Этот контекст включает:

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

Пример использования контекста:

module.exports = function (source) {
  const options = this.getOptions();

  const resourcePath = this.resourcePath;

  if (options.debug) {
    return `/* ${resourcePath} */\n` + source;
  }

  return source;
};

Передача опций через inline-объявление loader

Помимо конфигурационного файла, параметры могут передаваться прямо в импорте модуля.

import data from 'custom-loader?prefix=LOG!./file.txt';

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


Особенности передачи сложных объектов

Параметры загрузчика могут включать вложенные структуры:

options: {
  transform: {
    trim: true,
    replace: {
      from: 'a',
      to: 'b'
    }
  }
}

Внутри загрузчика такие данные доступны без дополнительной сериализации:

module.exports = function (source) {
  const { transform } = this.getOptions();

  let result = source;

  if (transform.trim) {
    result = result.trim();
  }

  if (transform.replace) {
    result = result.replace(transform.replace.from, transform.replace.to);
  }

  return result;
};

Поток выполнения и неизменяемость опций

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


Сочетание опций с контекстными параметрами Webpack

Опции загрузчика дополняются параметрами контекста:

  • this.mode
  • this.rootContext
  • this.resourceQuery
  • this.resourcePath

Пример комбинированного использования:

module.exports = function (source) {
  const options = this.getOptions();

  if (this.mode === 'production' && options.minify) {
    return source.replace(/\s+/g, ' ');
  }

  return source;
};

Расширенные сценарии конфигурации

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

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: (info) => {
          return {
            loader: 'custom-loader',
            options: {
              filename: info.resourcePath,
              hash: Date.now()
            }
          };
        }
      }
    ]
  }
};

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


Взаимодействие опций с кешированием загрузчиков

Webpack кеширует результаты работы загрузчиков на основе:

  • входного содержимого
  • идентификатора загрузчика
  • переданных опций

Любое изменение options приводит к инвалидированию кеша, что обеспечивает корректность пересборки:

module.exports = function (source) {
  const options = this.getOptions();

  this.cacheable && this.cacheable();

  return source + options.suffix;
};

Типичные ошибки при передаче опций

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

Неверный подход:

options: {
  formatter: () => {}
}

Корректный подход предполагает использование строковых идентификаторов или внешних модулей:

options: {
  formatter: 'uppercase'
}

Согласованность API между версиями Webpack

Эволюция передачи опций загрузчика прошла несколько стадий:

  • query string в ранних версиях
  • this.query как основной доступ
  • loader-utils как промежуточный стандарт
  • this.getOptions() как текущая модель

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