Asset Modules в Webpack представляют собой встроенный механизм обработки статических ресурсов, который заменил необходимость использовать отдельные загрузчики вроде file-loader и url-loader. В современных версиях Webpack (начиная с 5) работа с изображениями, шрифтами, медиафайлами и другими бинарными ресурсами выполняется через нативные типы модулей, что упрощает конфигурацию сборки, уменьшает количество зависимостей и делает поведение системы более предсказуемым.
До появления Asset Modules обработка файлов требовала явного подключения специализированных загрузчиков:
Такая схема приводила к дублированию логики и усложнению конфигурации. Asset Modules объединяют эти сценарии в единый механизм, встроенный в ядро Webpack.
Ключевая идея заключается в том, что файл рассматривается не как внешний ресурс, а как модуль с определённым типом поведения.
Webpack 5 вводит четыре базовых типа модулей для работы с ресурсами.
Тип asset/resource полностью заменяет file-loader. При обработке файла он копируется в итоговую директорию сборки, а в коде возвращается URL на этот файл.
Поведение:
Используется для:
Тип asset/inline заменяет url-loader в режиме инлайна. Вместо создания отдельного файла содержимое преобразуется в Base64-строку и вставляется прямо в JavaScript-бандл.
Поведение:
Используется для:
Тип asset/source заменяет raw-loader. Файл импортируется как строка без преобразования.
Поведение:
Используется для:
Универсальный тип asset позволяет Webpack автоматически выбирать стратегию между resource и inline на основе размера файла.
Поведение:
Используется для:
Настройка выполняется через module.rules без подключения внешних загрузчиков.
Базовый пример:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif|svg)$/i,
type: 'asset/resource'
}
]
}
};
В этом случае все изображения будут копироваться в output директорию и экспортироваться как URL.
Asset Modules поддерживают шаблоны именования через output.assetModuleFilename.
Пример:
module.exports = {
output: {
assetModuleFilename: 'assets/[hash][ext][query]'
}
};
Доступные шаблоны:
Гибкое именование позволяет:
Для типа asset можно задать правило размера:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
}
}
]
}
};
Логика:
Такой подход заменяет url-loader с параметром limit.
Старый подход:
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash].[ext]'
}
}
]
}
Новый подход:
{
test: /\.(png|jpg)$/,
type: 'asset/resource'
}
И конфигурация имени:
output: {
assetModuleFilename: '[name].[contenthash][ext]'
}
Результат:
Старый вариант:
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8000,
name: '[name].[hash].[ext]'
}
}
]
}
Новый вариант:
{
test: /\.(png|jpg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8000
}
}
}
Разница заключается в том, что логика инлайнинга становится частью ядра Webpack, а не внешнего пакета.
Asset Modules интегрируются с системой оптимизации Webpack:
Ключевая особенность заключается в том, что ассеты становятся частью графа модулей, а не внешними файлами, что позволяет Webpack учитывать их при анализе зависимостей.
При импорте ассетов в TypeScript требуется объявление модулей:
declare module '*.png' {
const src: string;
export default src;
}
Это связано с тем, что Webpack возвращает строковый URL, который не типизирован по умолчанию.
Чаще всего используются asset/resource или asset:
{
test: /\.(woff|woff2|ttf|otf)$/i,
type: 'asset/resource'
}
Шрифты почти всегда выносятся в отдельные файлы для оптимизации кеширования.
SVG может обрабатываться по-разному:
Выбор зависит от сценария использования: иконки, логотипы или сложные графические элементы.
Аудио и видео обычно используют asset/resource из-за размера:
{
test: /\.(mp4|mp3|webm)$/i,
type: 'asset/resource'
}
Asset Modules автоматически работают с импортами внутри CSS через url():
background-image: url('./image.png');
Webpack применяет тот же pipeline обработки, что и для JavaScript импортов.
Ключевые преимущества перед file-loader и url-loader:
Несмотря на универсальность, Asset Modules имеют особенности:
В большинстве случаев эти ограничения компенсируются простотой архитектуры.
rules: [
{
test: /\.svg$/,
type: 'asset/resource'
},
{
test: /\.inline.svg$/,
type: 'asset/inline'
}
]
{
test: /\.(png|jpg|svg|woff2)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 5000
}
}
}
Переход на Asset Modules меняет подход к организации фронтенда:
В результате сборка становится более прозрачной и управляемой, а поведение ассетов — более детерминированным.