В системе загрузчиков Webpack конфигурация передаётся через унифицированный механизм, позволяющий параметризовать поведение трансформаций файлов. Каждый загрузчик представляет собой функцию, которая получает входные данные модуля и контекст выполнения, а также доступ к пользовательским параметрам, определяющим логику обработки.
Передача опций загрузчику является ключевым элементом архитектуры, поскольку один и тот же загрузчик может использоваться в разных сценариях с различным поведением без изменения исходного кода.
Современный стандарт 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.
В актуальной архитектуре загрузчиков Webpack рекомендуется
использовать this.getOptions().
module.exports = function (source) {
const options = this.getOptions();
const prefix = options.prefix || '';
return prefix + source;
};
Такой подход заменяет устаревшие механизмы и обеспечивает корректную работу с JSON Schema валидацией опций.
Ранее параметры передавались непосредственно в строке подключения загрузчика:
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;
};
Данный способ считается устаревшим и не рекомендуется к использованию, поскольку усложняет парсинг и нарушает единообразие конфигурации.
До появления встроенного метода 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 }
}
]
}
]
}
}
Каждый загрузчик получает только свои параметры, без автоматического наследования между слоями цепочки.
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;
};
Помимо конфигурационного файла, параметры могут передаваться прямо в импорте модуля.
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 не влияет на другие модули или повторные вызовы
загрузчика, поскольку каждый вызов получает собственный экземпляр
конфигурации.
Опции загрузчика дополняются параметрами контекста:
this.modethis.rootContextthis.resourceQuerythis.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'
}
Эволюция передачи опций загрузчика прошла несколько стадий:
this.query как основной доступloader-utils как промежуточный стандартthis.getOptions() как текущая модельСовременная реализация ориентирована на строгую типизацию, предсказуемость и интеграцию со схемами валидации, что снижает вероятность ошибок конфигурации и повышает переносимость загрузчиков между проектами.