Управление именами выходных файлов

Механизм генерации имен по умолчанию

Parcel использует стратегию автоматической генерации имён выходных файлов, ориентированную на долгосрочное кеширование и минимизацию конфликтов между сборками. В стандартной конфигурации итоговые файлы получают:

  • имя исходного ресурса (entry point или модуль)
  • хеш содержимого
  • расширение, соответствующее типу результата

Пример типичного результата сборки:

app.8f3a91c2.js
styles.4c1d9e7a.css
logo.31b7d2.png

Хеширование основано на содержимом бандла. Любое изменение в коде или зависимостях приводит к изменению хеша, что обеспечивает корректное обновление кэша в браузере без дополнительных настроек.


Парадигма content hashing

Parcel применяет content hashing, при котором имя файла отражает фактическое содержимое:

  • одинаковое содержимое → одинаковый хеш
  • изменение кода → новый хеш
  • независимость от порядка сборки

Это критично для production-сценариев, где CDN и браузерный кеш должны хранить файлы максимально долго.

Пример логики:

main.js → main.a1b2c3d4.js
main.js (изменён) → main.f9e8d7c6.js

Шаблоны именования файлов

Parcel поддерживает шаблонные placeholders для управления именами выходных файлов. Эти шаблоны можно задавать через конфигурацию targets.

Основные токены:

  • [name] — исходное имя файла
  • [hash] — короткий хеш содержимого
  • [contentHash] — полный хеш содержимого
  • [ext] — расширение файла

Пример конфигурации:

{
  "targets": {
    "default": {
      "distDir": "dist",
      "fileName": "[name].[contentHash].[ext]"
    }
  }
}

Результат сборки:

index.91c8f2a1.js
index.3a8b91c0.css

Разделение конфигурации по таргетам

Parcel поддерживает множественные цели сборки (targets), каждая из которых может иметь собственные правила именования.

Пример:

{
  "targets": {
    "browser": {
      "distDir": "dist/web",
      "fileName": "[name]-web-[contentHash].[ext]"
    },
    "node": {
      "distDir": "dist/server",
      "fileName": "[name].[ext]"
    }
  }
}

Поведение:

  • браузерная сборка использует хешированные имена для кеширования
  • серверная сборка может обходиться без хешей, поскольку выполняется в Node.js

Управление структурой выходных директорий

Помимо имени файла, Parcel позволяет управлять расположением сборки через distDir.

Пример:

{
  "targets": {
    "default": {
      "distDir": "build/output"
    }
  }
}

Это влияет на корневую папку, внутри которой сохраняются все артефакты сборки.

Структура может выглядеть так:

build/output/
  index.91c8c2.js
  vendor.12ab34.js
  styles.aa9988.css

Контроль имени входных точек

Parcel сохраняет логическую связь между входным файлом и выходным бандлом. Имя entry point часто становится основой для [name].

Пример:

src/main.js → main.[hash].js
src/admin/dashboard.js → dashboard.[hash].js

При этом вложенность может влиять на генерацию имени в зависимости от структуры проекта.


Управление именами ассетов (изображения, шрифты, медиа)

Parcel обрабатывает статические ресурсы как отдельные ассеты, применяя ту же систему именования.

Пример шаблона:

{
  "targets": {
    "default": {
      "fileName": "[name].[contentHash].[ext]"
    }
  }
}

Результаты:

logo.3f21c9.png
font.9a8b77.woff2
background.11cc22.jpg

Для медиаресурсов особенно важно использовать [contentHash], поскольку браузер активно кеширует изображения и шрифты.


Переопределение имени через импорты

Parcel позволяет влиять на имя ассета через сам импорт.

Пример:

import logoUrl from "./logo.png";

Фактическое имя файла определяется конфигурацией, но логическое имя (logo) участвует в формировании [name].

Варианты влияния:

  • имя файла в исходниках
  • путь импорта
  • настройки namer-плагинов

Плагинная система namers

Parcel использует архитектуру расширений, где генерация имён может быть переопределена через namer plugins.

Namer отвечает за финальное имя бандла.

Пример поведения кастомного namer:

  • группировка файлов по типу
  • добавление префиксов окружения
  • формирование структур по доменам приложения

Концептуально:

entry → bundle graph → namer → output filename

Это позволяет реализовать нестандартные стратегии:

  • feature-based naming
  • domain-based bundling
  • multi-tenant builds

Хеши и стратегии стабильности

Parcel поддерживает несколько видов хеширования:

  • content hash — полный хеш содержимого
  • chunk hash — хеш части графа зависимостей
  • derived hash — производный хеш от зависимостей

Использование [contentHash] обеспечивает максимальную стабильность кеша.

Пример:

{
  "targets": {
    "default": {
      "fileName": "[name].[contentHash].js"
    }
  }
}

Публичный путь и влияние на имена

Параметр publicUrl влияет не на само имя файла, но на итоговые ссылки на него.

Пример:

{
  "targets": {
    "default": {
      "publicUrl": "/static/",
      "fileName": "[name].[contentHash].[ext]"
    }
  }
}

Результат:

/static/app.91c8c2.js
/static/styles.a12b34.css

Это критично при деплое на CDN или подкаталоги.


Поведение при разработке и production

В dev-режиме Parcel может использовать упрощённые имена:

app.js
styles.css

В production включается хеширование:

app.91c8c2.js
styles.a12b34.css

Такое разделение позволяет:

  • ускорить сборку в разработке
  • обеспечить стабильное кеширование в продакшене

Конфликты имён и их разрешение

Parcel автоматически избегает конфликтов:

  • одинаковые имена из разных директорий
  • пересечения имен entry points
  • коллизии ассетов

Стратегия:

  1. анализ графа зависимостей
  2. генерация уникального идентификатора
  3. добавление хеша или контекста пути

Пример:

utils.js → utils.1a2b3c.js
src/utils.js → utils.9f8e7d.js

Влияние оптимизации на имена файлов

При включённой оптимизации (production режим):

  • бандлы разделяются (code splitting)
  • появляются chunk-файлы
  • каждый chunk получает собственное имя

Пример:

main.91c8.js
vendor.33aa.js
lazy-load.77ff.js

Это напрямую влияет на стратегию именования, поскольку количество файлов увеличивается динамически.


Практика построения предсказуемой схемы имен

Стабильная схема именования обычно опирается на комбинацию:

  • [name] — читаемость
  • [contentHash] — кеширование
  • [ext] — корректная типизация

Рекомендуемая структура:

[name].[contentHash].[ext]

Для специализированных сборок:

[name]-[env].[contentHash].[ext]

где env может задаваться через разные targets.


Именование в многомодульных приложениях

В крупных приложениях Parcel формирует множество бандлов:

  • entry bundles
  • async chunks
  • shared dependencies

Именование становится частью архитектуры:

  • предсказуемость загрузки
  • контроль кеша
  • диагностика в production

Пример структуры:

home.1a2b.js
dashboard.3c4d.js
shared.vendor.9f8e.js

Каждый файл отражает не только содержимое, но и роль в графе зависимостей.