Тип asset в Webpack 5 относится к системе Asset Modules
и предназначен для автоматического выбора способа обработки файлов в
зависимости от их размера. Этот режим объединяет поведение типов
asset/resource и asset/inline, позволяя
Webpack самостоятельно принимать решение:
Такой подход уменьшает объём конфигурации и делает обработку ресурсов более гибкой.
assetПри использовании типа asset Webpack анализирует размер
файла:
asset/inline;asset/resource.Фактически asset представляет собой автоматический
переключатель между двумя стратегиями.
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|svg)$/i,
type: 'asset'
}
]
}
};
В такой конфигурации:
Webpack использует параметр:
parser.dataUrlCondition.maxSize
По умолчанию лимит составляет:
8 KB (8192 байта)
Если файл меньше 8 KB:
image.png → Base64 → bundle.js
Если файл больше:
image.png → отдельный файл → dist/
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 20 * 1024
}
}
}
]
}
};
Здесь лимит увеличен до:
20 KB
Если файл попадает под ограничение размера, Webpack преобразует его в Data URL.
Исходный импорт:
import logo fr om './logo.png';
Результат:
const logo =
"data:image/png;base64,iVBORw0KGgoAAAANS...";
Такой файл:
Если размер превышает лимит:
import image from './photo.jpg';
Webpack генерирует:
dist/
images/
photo.a1b2c3.jpg
А импорт превращается в строку:
const image = "/images/photo.a1b2c3.jpg";
assetВместо ручного разделения:
{
test: /\.svg$/,
type: 'asset/inline'
}
и:
{
test: /\.png$/,
type: 'asset/resource'
}
можно использовать единый универсальный механизм.
Маленькие файлы:
Большие файлы:
Webpack сам определяет наиболее подходящую стратегию без необходимости вручную анализировать каждый файл.
assetInline-файлы попадают внутрь bundle:
bundle.js
При большом количестве встроенных ресурсов:
Кодирование Base64 делает данные примерно на:
33% больше
Например:
| Исходный файл | После Base64 |
|---|---|
| 3 KB | ~4 KB |
| 6 KB | ~8 KB |
Поэтому встраивание крупных файлов неэффективно.
Если изображение встроено в bundle:
assetТип asset особенно полезен для:
asset подходит
плохоНежелательно использовать автоматический режим для:
В таких случаях лучше явно использовать:
type: 'asset/resource'
module.exports = {
module: {
rules: [
{
test: /\.svg$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
}
}
]
}
};
SVG обычно хорошо сжимаются и имеют маленький размер, поэтому inline-режим особенно эффективен.
При использовании resource-режима можно управлять именованием:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg)$/i,
type: 'asset',
generator: {
filename: 'images/[name].[contenthash][ext]'
}
}
]
}
};
contenthashcontenthash помогает организовать долгосрочное
кэширование.
Пример:
logo.ae34f1.png
При изменении содержимого:
logo.b8129c.png
Браузер понимает, что файл обновился.
asset с
другими типами| Тип | Поведение |
|---|---|
asset/resource |
Всегда отдельный файл |
asset/inline |
Всегда Base64 |
asset/source |
Исходный текст |
asset |
Автоматический выбор |
url-loaderДо Webpack 5 аналогичная логика реализовывалась через:
url-loader
Пример старого подхода:
{
test: /\.(png|jpg)$/i,
use: {
loader: 'url-loader',
options: {
lim it: 8192
}
}
}
Webpack 5 заменил это встроенной системой Asset Modules.
Не требуется установка:
url-loader
file-loader
raw-loader
Настройка выполняется напрямую через:
type: 'asset'
Asset Modules работают быстрее и глубже интегрированы в процесс сборки.
src/
images/
icon.svg
photo.jpg
index.js
module.exports = {
module: {
rules: [
{
test: /\.(svg|png|jpg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024
}
},
generator: {
filename: 'assets/[hash][ext]'
}
}
]
}
};
import icon from './images/icon.svg';
import photo from './images/photo.jpg';
console.log(icon);
console.log(photo);
data:image/svg+xml;base64,...
/assets/82fd31a2.jpg
Маленькие файлы:
Избыточный inline:
Типичные значения:
| Размер | Использование |
|---|---|
| 2–4 KB | Очень маленькие иконки |
| 8 KB | Стандартный компромисс |
| 10–20 KB | UI-графика |
| >20 KB | Обычно уже неэффективно |
Для разных типов ресурсов часто используют разные ограничения.
{
test: /\.svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
}
}
{
test: /\.png$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024
}
}
}
{
test: /\.(woff2?|ttf)$/i,
type: 'asset/resource'
}
При импорте изображений из CSS:
background-image: url('./bg.png');
Webpack также применяет правила asset.
Если изображение маленькое:
background-image: url(data:image/png;base64,...);
Если большое:
background-image: url(/assets/bg.a1b2.png);
При извлечении CSS:
MiniCssExtractPlugin.loader
ресурсы продолжают обрабатываться через Asset Modules без изменений.
SVG особенно хорошо подходят для inline-режима:
Но слишком крупные SVG могут значительно увеличить bundle.
Для анализа поведения asset полезно проверять:
dist/
и содержимое bundle.
Также удобно использовать:
webpack-bundle-analyzer
для поиска слишком крупных inline-ресурсов.
maxSizemaxSize: 200 * 1024
Проблемы:
Встраивание шрифтов часто ухудшает производительность:
woff2 → Base64 → bundle.js
Обычно шрифты лучше хранить отдельно.
SVG, PNG и JPG имеют разные особенности. Универсальный лимит часто оказывается неоптимальным.
Часто используют гибридный подход:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
type: 'asset'
},
{
test: /\.(png|jpg)$/i,
type: 'asset/resource'
}
]
}
};
SVG автоматически встраиваются при необходимости, а фотографии всегда остаются отдельными файлами.