В Webpack система работы с файлами-ассетами построена вокруг
концепции Asset Modules, которая заменяет необходимость в
file-loader, url-loader и частично
raw-loader. Центральным элементом управления тем, как будут
называться и куда будут помещаться файлы, выступает
output.assetModuleFilename и локальные переопределения
через generator.filename.
Ключевая настройка:
output: {
assetModuleFilename: 'assets/[hash][ext][query]'
}
Она задаёт дефолтный шаблон имени для всех ассетов, которые обрабатываются через Asset Modules и не имеют локального переопределения.
Если в конфигурации указано:
output: {
assetModuleFilename: 'static/media/[hash][ext]'
}
то любые файлы, попадающие под тип:
asset/resourceasset/inlineasset (автовыбор)будут сохраняться в указанную директорию с именем, основанным на хеше.
Webpack поддерживает набор специальных токенов, которые подставляются в процессе сборки.
Глобальный хеш сборки или ассета (в зависимости от контекста использования).
images/8f3a1c9d8c.png
Используется для:
Более стабильный вариант, основанный на содержимом конкретного файла.
Чаще применяется через generator.filename, но также
может использоваться в общих шаблонах.
Исходное имя файла без расширения:
logo.png → logo
Пример:
assetModuleFilename: 'assets/[name].[hash][ext]'
Расширение файла, включая точку:
.png, .jpg, .svg
Важно: Webpack сохраняет оригинальное расширение, если оно не переопределено loader-логикой.
Относительный путь исходного файла от context.
Используется для сохранения структуры проекта:
assetModuleFilename: 'assets/[path][name][hash][ext]'
Если файл находится в:
src/images/icons/logo.svg
результат может выглядеть как:
assets/images/icons/logoa1b2c3.svg
Сохраняет query-параметры, если они присутствуют в запросе импорта:
import img from './logo.png?inline'
Работает как глобальный fallback для всех ассетов.
Позволяет переопределить шаблон на уровне конкретного правила:
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource',
generator: {
filename: 'images/[name][contenthash][ext]'
}
}
]
}
Локальная настройка всегда имеет приоритет над глобальной.
Файлы сохраняются на диск.
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|svg)$/,
type: 'asset/resource'
}
]
}
}
Результат:
dist/assets/8c1f3a.png
Файлы не сохраняются, а преобразуются в base64 URI.
В этом случае assetModuleFilename не применяется, так
как физического файла нет.
Webpack автоматически решает:
Порог задаётся через:
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
}
Иерархия применения шаблонов:
generator.filename (Rule-level)output.assetModuleFilename (global fallback)output: {
assetModuleFilename: 'assets/[hash][ext]'
}
Результат:
assets/a1b2c3d4.png
assets/f9e8d7c6.svg
Плюс: простота Минус: отсутствие структуры
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource',
generator: {
filename: 'images/[contenthash][ext]'
}
},
{
test: /\.woff2$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[contenthash][ext]'
}
}
]
}
Структура:
images/1a2b3c.png
fonts/9f8e7d.woff2
output: {
assetModuleFilename: '[path][name][contenthash][ext]'
}
Результат:
src/images/icons/logo.8f3a.png
или в dist:
dist/src/images/icons/logo.8f3a.png
Такой подход сохраняет читаемость, но может засорять output.
Использование hash и contenthash напрямую
влияет на стратегию кеширования браузера.
assetModuleFilename: 'assets/[name].[contenthash][ext]'
При изменении изображения:
assetModuleFilename определяет имя файла, но не путь
доступа к нему.
output: {
publicPath: '/static/',
assetModuleFilename: 'images/[hash][ext]'
}
Результат в runtime:
/static/images/8c1f3a.png
Хотя mode не меняет шаблоны напрямую, он влияет на:
target: 'web' чаще предполагает строгую стратегию
кеширования через contenthash.
assetModuleFilename: '[hash][ext]'
Проблема:
assetModuleFilename: 'assets/[hash][ext]'
Результат:
assetModuleFilename: '[name][ext]'
Проблема:
Хотя относится к CSS, часто используется вместе с asset naming:
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
Логика именования становится единообразной между CSS и assets.
Хотя splitChunks не управляет файлами напрямую, он
влияет на:
output: {
assetModuleFilename: 'assets/[name].[contenthash][ext]'
}
Баланс между:
generator: {
filename: 'media/images/[contenthash][ext]'
}
generator: {
filename: 'media/fonts/[contenthash][ext]'
}
Используется в крупных приложениях с большим количеством ассетов.
assetModuleFilename: '[path][name][ext]'
Используется в разработке: