Тип asset/inline в Webpack предназначен для встраивания
файлов непосредственно в итоговый JavaScript-бандл в виде строки Data
URL. Чаще всего используется Base64-кодирование, хотя Webpack способен
применять и другие форматы представления данных.
После обработки ресурс перестаёт существовать как отдельный физический файл в директории сборки. Вместо ссылки на файл в коде появляется строка вида:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
Такой подход позволяет полностью исключить дополнительные HTTP-запросы к небольшим ресурсам.
asset/inlineПри импорте файла Webpack:
Пример:
import logo fr om './logo.png';
console.log(logo);
Результат:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
Файл logo.png не копируется в папку
dist.
asset/inlineБазовая конфигурация:
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset/inline'
}
]
}
};
Теперь каждый PNG-файл будет автоматически встроен в бандл.
Base64 — это способ представления бинарных данных в текстовом формате.
Например:
Hello
После кодирования:
SGVsbG8=
Для изображений или шрифтов данные становятся значительно длиннее:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
Data URL состоит из нескольких частей:
data:[MIME-TYPE];base64,[DATA]
Пример:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0...
Разбор:
| Часть | Назначение |
|---|---|
data: |
Префикс Data URL |
image/svg+xml |
MIME-тип файла |
base64 |
Формат кодирования |
PHN2Zy... |
Закодированные данные |
src/
├── index.js
└── images/
└── icon.png
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset/inline'
}
]
}
};
import icon from './images/icon.png';
const image = document.createElement('img');
image.src = icon;
document.body.append(image);
const icon = "data:image/png;base64,iVBORw0KGgoAAAANS...";
asset/inlineМаленькие PNG-файлы:
16x16
24x24
32x32
Небольшие SVG особенно хорошо подходят для inline-встраивания.
{
test: /\.svg$/,
type: 'asset/inline'
}
SVG-файлы часто имеют маленький размер и отлично сжимаются.
Иногда inline используется для небольших WOFF2-файлов:
{
test: /\.woff2$/,
type: 'asset/inline'
}
.button {
background-image: url('./icon.png');
}
Webpack преобразует путь в Data URL.
asset/inlineБез inline:
index.html
main.js
logo.png
icon.png
font.woff2
Браузер выполняет несколько запросов.
С inline:
index.html
main.js
Все ресурсы встроены в код.
Особенно полезно для:
В папке сборки:
dist/
└── bundle.js
Не создаются дополнительные изображения.
Меньше файлов:
asset/inlineBase64 увеличивает размер данных примерно на 33%.
Например:
| Оригинал | Base64 |
|---|---|
| 3 KB | ~4 KB |
| 30 KB | ~40 KB |
Большой встроенный Base64:
const img = "data:image/png;base64,....";
увеличивает размер бандла, который:
Если изображение встроено:
bundle.js
то браузер не может закэшировать картинку отдельно.
Даже небольшое изменение JS-инструкций инвалидирует весь бандл.
В sourcemap и devtools появляются огромные строки Base64.
asset/inlineПодходит для:
| Тип ресурса | Рекомендация |
|---|---|
| SVG-иконки | Отлично |
| Маленькие PNG | Хорошо |
| Мини-шрифты | Допустимо |
| Большие изображения | Плохо |
| Видео | Недопустимо |
Главное правило:
Inline используется только для небольших файлов.
Практические ориентиры:
| Размер | Подход |
|---|---|
| до 2 KB | Отлично |
| до 4 KB | Хорошо |
| 4–10 KB | Осторожно |
| более 10 KB | Лучше отдельный файл |
asset/inline и asset/resourceasset/resourceСоздаёт физический файл:
dist/
├── main.js
└── logo.a1b2c3.png
Импорт:
import logo from './logo.png';
Результат:
"/logo.a1b2c3.png"
asset/inlineНичего не создаёт:
dist/
└── main.js
Результат:
"data:image/png;base64,iVBOR..."
asset/inline и asset/sourceasset/inlineПреобразует файл в Data URL:
data:image/svg+xml;base64,...
asset/sourceВозвращает содержимое файла как строку:
"<svg>...</svg>"
Это принципиально разные механизмы.
.block {
background: url('./bg.png');
}
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset/inline'
}
]
}
};
background:
url(data:image/png;base64,iVBORw0KGgoAAAANS...)
SVG особенно хорошо подходит для встраивания.
Пример:
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40"/>
</svg>
После обработки:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0...
SVG:
PNG:
Webpack поддерживает тип asset, который автоматически
выбирает способ обработки.
Пример:
{
test: /\.(png|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
}
}
Логика:
| Размер файла | Результат |
|---|---|
| < 4 KB | inline |
| > 4 KB | resource |
dataUrlConditionПараметр:
maxSize
указывает максимальный размер файла для inline-встраивания.
Пример:
maxSize: 8 * 1024
означает:
8 KB
{
test: /\.svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 2 * 1024
}
}
}
{
test: /\.png$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1 * 1024
}
}
}
logo.png
может кешироваться независимо.
main.js
содержит всё внутри себя.
Изменение одной строки JS:
console.log('test');
может привести к повторной загрузке всех встроенных изображений.
Inline-ресурсы участвуют в графе зависимостей Webpack.
Если модуль не используется:
import icon from './icon.svg';
то изображение тоже удаляется из бандла.
Во время разработки:
type: 'asset/inline'
ускоряет отображение мелких ресурсов, потому что dev server не отдаёт множество отдельных файлов.
Но слишком большие inline-данные ухудшают HMR и скорость обновления.
Большие inline-ресурсы:
data:image/png;base64,...
могут сильно увеличивать размер source map.
Особенно проблемно:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
type: 'asset/inline'
},
{
test: /\.png$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 2 * 1024
}
}
},
{
test: /\.(woff2|woff)$/i,
type: 'asset/resource'
}
]
}
};
Наиболее распространённая стратегия:
| Ресурс | Подход |
|---|---|
| SVG-иконки | inline |
| Мелкие PNG | auto asset |
| Фото | resource |
| Видео | resource |
| Шрифты | resource |
url-loaderДо Webpack 5 использовался:
url-loader
Пример:
{
test: /\.png$/,
use: {
loader: 'url-loader',
options: {
lim it: 4096
}
}
}
В Webpack 5 этот механизм заменён Asset Modules.
url-loaderНе нужны:
file-loader
url-loader
raw-loader
Достаточно:
type: 'asset/inline'
Asset Modules встроены в ядро Webpack.
Плохо:
banner.jpg — 500 KB
Результат:
Проблемы:
Конфигурация:
{
test: /\.(png|jpg|svg|woff2)$/,
type: 'asset/inline'
}
обычно приводит к деградации производительности.
Хотя Base64 увеличивает размер файла, gzip частично компенсирует потери.
Особенно эффективно для:
Но бинарные PNG всё равно часто проигрывают отдельным файлам.
Раньше inline активно использовался для уменьшения количества HTTP-запросов.
С появлением HTTP/2 ситуация изменилась:
Поэтому сегодня asset/inline применяется более
избирательно.
menu.svg
close.svg
search.svg
Небольшие SVG-логотипы.
Критические изображения интерфейса.
Inline помогает избежать внешних запросов.
hero.jpg
background.jpg
intro.mp4
sound.mp3
Roboto-Regular.woff2