Webpack Loaders
Зачем нужно
Loaders — это трансформаторы файлов в Webpack. Webpack из коробки понимает только JS и JSON. Loaders позволяют импортировать CSS, изображения, TypeScript, SCSS и вообще всё что угодно — каждый loader конвертирует файл в модуль, понятный Webpack.
Где используется
- Транспиляция JS/TS (babel-loader, ts-loader)
- Обработка стилей (css-loader, sass-loader)
- Загрузка ресурсов (file-loader, url-loader)
- Линтинг (eslint-loader)
- Шаблоны (html-loader, pug-loader)
Как работают loaders
Файл → Loader 1 → Loader 2 → Loader 3 → Webpack
Порядок выполнения: СПРАВА → НАЛЕВО (снизу → вверх)
use: ['style-loader', 'css-loader', 'postcss-loader']
▲ ▲ ▲
3 2 1
// webpack.config.js — базовая структура
module.exports = {
module: {
rules: [
{
test: /\.ext$/, // RegExp для файлов
exclude: /node_modules/, // Что исключить
use: 'loader-name', // Один loader
// или
use: ['loader-a', 'loader-b'], // Цепочка
// или с опциями
use: [
{
loader: 'loader-name',
options: { /* настройки */ },
},
],
},
],
},
};
babel-loader
Транспилирует современный JavaScript (ES6+) и JSX в код, понятный старым браузерам:
npm install --save-dev babel-loader @babel/core @babel/preset-env
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead', // Браузеры
useBuiltIns: 'usage', // Полифилы по необходимости
corejs: 3,
}],
],
plugins: [
'@babel/plugin-proposal-class-properties',
],
cacheDirectory: true, // Кэширование для скорости
},
},
}
// .babelrc — альтернативно вынести конфиг
{
"presets": [
["@babel/preset-env", { "targets": "> 0.25%, not dead" }],
"@babel/preset-react" // Для JSX
]
}
css-loader и style-loader
npm install --save-dev css-loader style-loader
// css-loader — разбирает CSS, обрабатывает @import и url
// style-loader — вставляет CSS в DOM через <style> тег
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
// 1. css-loader парсит CSS
// 2. style-loader вставляет в <style>
}
CSS Modules
{
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
},
],
}
// Использование
import styles from './Button.module.css';
// styles = { primary: 'Button__primary--a3b2c', active: '...' }
element.className = styles.primary;
postcss-loader
npm install --save-dev postcss-loader postcss autoprefixer
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
'autoprefixer', // Добавляет вендорные префиксы
],
},
},
},
],
}
sass-loader (SCSS)
npm install --save-dev sass-loader sass
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader', // Компилирует SCSS → CSS
],
}
ts-loader
Компилирует TypeScript:
npm install --save-dev ts-loader typescript
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader',
}
// Альтернатива — babel-loader с @babel/preset-typescript
// Быстрее, но без проверки типов
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
],
},
},
}
Работа с ресурсами (Webpack 5)
В Webpack 5 встроенная обработка ресурсов заменяет file-loader, url-loader, raw-loader:
// asset/resource — файл копируется в output (как file-loader)
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset/resource',
generator: {
filename: 'images/[name].[hash:8][ext]',
},
}
// asset/inline — файл встраивается как base64 (как url-loader)
{
test: /\.svg$/,
type: 'asset/inline',
}
// asset — автовыбор: маленькие → inline, большие → resource
{
test: /\.(png|jpg|gif)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024, // 8kb
},
},
}
// asset/source — содержимое как строка (как raw-loader)
{
test: /\.txt$/,
type: 'asset/source',
}
Устаревшие loaders (Webpack 4)
// file-loader — копирует файл, возвращает URL
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'file-loader',
options: { name: '[name].[hash:8].[ext]', outputPath: 'images/' },
},
}
// url-loader — маленькие файлы → base64
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: { limit: 8192, fallback: 'file-loader' },
},
}
html-loader
npm install --save-dev html-loader
{
test: /\.html$/,
use: {
loader: 'html-loader',
options: {
// Обрабатывает src в img, href в link и т.д.
sources: true,
minimize: true,
},
},
}
Написание собственного loader
// my-loader.js
module.exports = function(source) {
// source — содержимое файла как строка
// this.query — опции из конфига
// Пример: заменить все TODO на DONE
const result = source.replace(/TODO/g, 'DONE');
// Вернуть трансформированный код
return result;
};
// Асинхронный loader
module.exports = function(source) {
const callback = this.async;
someAsyncOperation(source)
.then(result => callback(null, result))
.catch(err => callback(err));
};
// Подключение в конфиге
{
test: /\.js$/,
use: path.resolve('./my-loader.js'),
}
Частые ошибки
- Неправильный порядок loaders —
['css-loader', 'style-loader']вместо['style-loader', 'css-loader'] - Не исключают node_modules —
babel-loaderобрабатывает тысячи файлов из зависимостей - file-loader в Webpack 5 — file-loader, url-loader, raw-loader устарели, использовать
type: 'asset' - Конфликт CSS Modules — обычный CSS и CSS Modules нужны разные rules
- Нет cacheDirectory — babel-loader без кэша медленно перекомпилирует при каждом изменении
Практика
- Настроить babel-loader для транспиляции ES6+ → ES5
- Подключить css-loader + style-loader, импортировать CSS в JS
- Настроить CSS Modules с уникальными именами классов
- Добавить sass-loader для SCSS
- Настроить обработку изображений через
type: 'asset'
Связанные темы
- Webpack — общая настройка Webpack
- Webpack plugins — расширение функциональности
- Vite — альтернатива без loaders