10. Asset Modules
Asset Modules — это новая встроенная система Webpack 5 для обработки статических ресурсов: изображений, шрифтов, SVG, медиафайлов. Она заменяет устаревшие лоадеры url-loader, file-loader и raw-loader без дополнительных зависимостей.
Устаревший подход (Webpack 4)
Заголовок раздела «Устаревший подход (Webpack 4)»# Нужно было устанавливать отдельно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' }, ]}Asset Modules в Webpack 5
Заголовок раздела «Asset Modules в Webpack 5»// 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' }, // автоматический выбор ]}Четыре типа Asset Modules
Заголовок раздела «Четыре типа Asset Modules»1. asset/resource — замена file-loader
Заголовок раздела «1. asset/resource — замена file-loader»Копирует файл в папку 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" />2. asset/inline — замена url-loader
Заголовок раздела «2. asset/inline — замена url-loader»Конвертирует файл в 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)3. asset/source — замена raw-loader
Заголовок раздела «3. asset/source — замена raw-loader»Возвращает строку с содержимым файла:
{ 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>'4. asset — умный выбор
Заголовок раздела «4. asset — умный выбор»Автоматически выбирает между 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 обрабатывает файлы разных размеров.