В системе сборки Parcel формирование имён итоговых файлов относится к отдельному этапу пайплайна трансформаций. За это отвечает слой Namer, который определяет, как именно будут называться сгенерированные ассеты после бандлинга, минификации и оптимизаций.
Parcel строит граф зависимостей, обрабатывает модули через трансформеры, а затем на этапе вывода (output) применяет namer-плагины, формируя финальные пути файлов. Это критически важный механизм для кеширования, организации структуры сборки и интеграции с CDN.
После завершения всех трансформаций Parcel получает набор ассетов: JavaScript-бандлы, CSS, изображения, шрифты и прочие ресурсы. На этом этапе каждый файл уже имеет содержимое, но ещё не имеет окончательного имени.
Задача Namer:
Parcel позволяет подключать несколько namer-стратегий, которые применяются по очереди.
По умолчанию Parcel использует встроенную стратегию, которая ориентируется на:
Типичный результат:
dist/index.8f3a1c.js
dist/styles.91bc44.css
dist/logo.2d91aa.png
Главный принцип — content hashing. Если содержимое файла меняется, меняется и его имя, что позволяет безопасно использовать агрессивное кеширование.
Parcel поддерживает систему шаблонов, которые используются внутри namer-логики. Основные токены:
[name]Имя исходного файла без расширения.
src/app.js → app.js
[ext]Расширение файла.
app.js → app.js
style.css → style.css
[hash]Хеш содержимого файла.
Используется для кеш-бастинга:
app.[hash].js → app.8f3a1c.js
[contenthash]Аналог [hash], но строго зависит от содержимого файла,
игнорируя метаданные.
Используется для стабильного кеширования.
[dir]Сохраняет структуру каталогов относительно входной точки.
src/pages/home.js → pages/home.js
[parent]Имя родительской директории.
Полезно при группировке модулей.
Parcel позволяет переопределять стратегию именования через
.parcelrc.
Пример подключения стандартного namer:
{
"namers": ["@parcel/namer-default"]
}
Можно комбинировать несколько namer-стратегий:
{
"namers": [
"@parcel/namer-hash",
"@parcel/namer-default"
]
}
Parcel применяет их последовательно: первая стратегия, которая возвращает результат, побеждает.
Если два файла после обработки получают одинаковое имя, Parcel автоматически:
Это предотвращает перезапись файлов в dist.
Namer тесно связан с системой кеширования Parcel.
app.js → app.1a2b3c.js
console.log("update");
app.9f8e7d.js
При этом старый файл остаётся в сборке до очистки, что позволяет CDN продолжать обслуживать старые версии.
Parcel позволяет создавать собственные namer-плагины.
export default function namer(asset) {
return `${asset.name}.${asset.hash}.${asset.type}`;
}
.parcelrc{
"namers": ["./my-namer.js"]
}
Каждый asset передаётся в namer с набором метаданных:
filePath — путь к исходному файлу;type — тип ресурса (js, css, png);bundleGraph — граф зависимостей;hash — вычисленный хеш;bundleBehavior — поведение бандла;env — контекст окружения.Эти данные позволяют строить сложные стратегии именования.
export default function namer(asset) {
if (asset.type === "js") {
return `scripts/${asset.name}.${asset.hash}.js`;
}
if (asset.type === "css") {
return `styles/${asset.name}.${asset.hash}.css`;
}
return `assets/${asset.filePath.split('/').pop()}`;
}
export default function namer(asset) {
const module = asset.filePath.split('/')[1];
return `${module}/${asset.name}.${asset.hash}.${asset.type}`;
}
export default function namer(asset) {
return `cdn/${asset.hash}.${asset.type}`;
}
Такая стратегия полностью игнорирует исходную структуру проекта и оптимизирует доставку через CDN.
Namer напрямую определяет эффективность HTTP-кеширования.
app.js
Любое изменение требует сброса кеша вручную.
app.3f91c2.js
Браузер воспринимает файл как новый ресурс, если изменилось содержимое.
Namer работает после:
Это означает, что хеш отражает финальное состояние файла, а не исходный код.
При динамическом импорте:
import("./module.js");
Parcel создаёт отдельный chunk, для которого также применяется namer.
Пример результата:
module.async.7c1a9b.js
Каждый async-бандл получает собственную стратегию именования.
Если namer возвращает недопустимый путь:
return "";
Parcel генерирует fallback-имя.
Если стратегия не учитывает хеш:
return `${asset.name}.js`;
возможны конфликты файлов при одинаковых именах в разных директориях.
В режиме разработки Parcel может:
Пример:
app.js (dev)
app.8f3a1c.js (prod)
Namer взаимодействует с:
Любое изменение в этих этапах может повлиять на итоговое имя через изменение хеша.
export default function namer(asset) {
return `eu/${asset.hash}.${asset.type}`;
}
export default function namer(asset) {
return `v2/${asset.name}.${asset.hash}.${asset.type}`;
}
export default function namer(asset) {
if (process.env.NODE_ENV === "production") {
return `${asset.name}.${asset.hash}.${asset.type}`;
}
return `${asset.name}.${asset.type}`;
}