Перейти к содержимому

10. Asset Modules

Asset Modules — это новая встроенная система Webpack 5 для обработки статических ресурсов: изображений, шрифтов, SVG, медиафайлов. Она заменяет устаревшие лоадеры url-loader, file-loader и raw-loader без дополнительных зависимостей.

Окно терминала
# Нужно было устанавливать отдельно
npm install --save-dev file-loader url-loader raw-loader
// webpack.config.js (старый способ)
module: {
rules: [
{ test: /\\.(png|jpg|gif)$/, use: 'file-loader' },
{ test: /\\.(png|jpg|gif)$/, use: { loader: 'url-loader', options: { limit: 8192 } } },
{ test: /\\.txt$/, use: 'raw-loader' },
]
}
// webpack.config.js (новый способ — без npm install!)
module: {
rules: [
{ test: /\\.(png|jpg|gif|svg)$/, type: 'asset/resource' },
{ test: /\\.svg$/, type: 'asset/inline' },
{ test: /\\.txt$/, type: 'asset/source' },
{ test: /\\.(png|jpg)$/, type: 'asset' }, // автоматический выбор
]
}

Копирует файл в папку output и возвращает URL:

{ test: /\\.(png|jpg|gif|webp)$/, type: 'asset/resource' }
// Настройка имени файла:
{
test: /\\.(png|jpg|gif)$/,
type: 'asset/resource',
generator: {
filename: 'images/[hash][ext][query]',
},
}
import logo from './logo.png';
// logo === '/dist/images/abc123.png'
// В JSX:
<img src={logo} alt="Logo" />

Конвертирует файл в base64 Data URL и инлайнит в бандл:

{
test: /\\.(png|jpg|gif)$/,
type: 'asset/inline',
}
import logo from './logo.png';
// logo === 'data:image/png;base64,iVBORw0KGgo...'
// Плюсы: нет отдельного HTTP запроса
// Минусы: увеличивает размер JS бандла
// Используйте только для маленьких файлов (<8 KB)

Возвращает строку с содержимым файла:

{ test: /\\.txt$/, type: 'asset/source' }
{ test: /\\.svg$/, type: 'asset/source' } // SVG как строка
{ test: /\\.graphql$/, type: 'asset/source' } // GraphQL запросы
import content from './readme.txt';
// content === 'Hello, World!\\nThis is a text file.'
import svgMarkup from './icon.svg';
// svgMarkup === '<svg xmlns="..."><path d="..."/></svg>'

Автоматически выбирает между resource и inline на основе размера файла:

{
test: /\\.(png|jpg|gif)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024, // 8 KB — меньше → inline, больше → resource
},
},
}
output: {
assetModuleFilename: 'assets/[hash][ext][query]',
// → dist/assets/a1b2c3d4.png
}
module: {
rules: [
// Изображения — умный выбор (< 8KB → inline, > 8KB → file)
{
test: /\\.(png|jpg|gif|webp|avif)$/i,
type: 'asset',
parser: { dataUrlCondition: { maxSize: 8192 } },
generator: { filename: 'images/[hash:8][ext]' },
},
// SVG — всегда как строка (для React компонентов)
// или resource (для <img>)
{
test: /\\.svg$/,
type: 'asset/resource',
generator: { filename: 'icons/[hash:8][ext]' },
},
// Шрифты — всегда как файл
{
test: /\\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: { filename: 'fonts/[name][ext]' },
},
// Видео и аудио
{
test: /\\.(mp4|webm|ogg|mp3|wav)$/i,
type: 'asset/resource',
generator: { filename: 'media/[hash:8][ext]' },
},
],
}

Ниже — интерактивный демо, показывающий как каждый тип Asset Module обрабатывает файлы разных размеров.