Медиа-файлы как URL

Медиа-файлы в сборке рассматриваются как полноценные модули, которые участвуют в графе зависимостей наравне с JavaScript, CSS и HTML. В Parcel любые изображения, шрифты, аудио- и видеофайлы превращаются в URL-адреса или инлайн-представления, в зависимости от размера и конфигурации, что позволяет унифицировать работу с ассетами и избавиться от ручного копирования ресурсов.

Parcel рассматривает медиа-файлы как часть графа модулей. При импорте изображения или другого ресурса происходит несколько этапов:

  • анализ типа файла через встроенные трансформеры;
  • помещение файла в граф зависимостей;
  • генерация оптимизированного выходного ресурса;
  • подстановка ссылки на итоговый файл в код.

Ключевой принцип заключается в том, что медиа-файл не просто копируется в папку сборки, а становится адресуемым модулем с предсказуемым результатом.

Превращение файла в URL

При импорте изображения в JavaScript результатом становится строка — URL на итоговый файл в сборке:

import logo from './assets/logo.png';

const img = document.createElement('img');
img.src = logo;

document.body.appendChild(img);

Переменная logo содержит строку вида:

/dist/logo.8f3a9c1d.png

Хеш в имени файла используется для кэширования и предотвращения конфликтов версий.

Аналогичный механизм применяется к другим типам медиа:

import sound from './assets/click.mp3';
import video from './assets/intro.mp4';

Каждый импорт возвращает URL, который можно использовать в DOM-API или передавать в стили.

Обработка изображений

Изображения являются наиболее частым типом медиа-ассетов. Parcel автоматически:

  • определяет формат (PNG, JPG, WebP, SVG);
  • оптимизирует файл при необходимости;
  • генерирует финальный путь;
  • управляет инлайном мелких изображений.

Инлайн изображений

Небольшие файлы могут быть встроены прямо в JavaScript как Data URL:

data:image/png;base64,...

Такой подход уменьшает количество HTTP-запросов, особенно для иконок и UI-элементов.

Использование в коде

import icon from './icons/edit.svg';

const button = document.createElement('button');
button.style.backgroundImage = `url(${icon})`;

SVG-файлы при этом могут сохранять как ссылочную форму, так и инлайн-представление в зависимости от конфигурации и размера.

Медиа-файлы в CSS

Parcel интегрирует обработку ассетов непосредственно в CSS-модули. Любые ссылки внутри url() становятся зависимостями сборщика.

.hero {
  background-image: url('./images/background.jpg');
}

При сборке путь автоматически переписывается:

.hero {
  background-image: url('/dist/background.91c3ab2d.jpg');
}

Шрифты как URL-ресурсы

Поддержка шрифтов работает аналогичным образом:

@font-face {
  font-family: "Inter";
  src: url("./fonts/Inter-Regular.woff2") format("woff2");
}

Parcel обрабатывает файл шрифта как модуль, копирует его в выходную директорию и подставляет корректный URL.

Единая система хеширования

Все медиа-файлы получают уникальные имена с содержательным хешем. Это обеспечивает:

  • кэш-бастинг при изменении содержимого;
  • отсутствие конфликтов имён;
  • стабильность ссылок между модулями.

Пример выходных файлов:

image.4f2a9c.png
video.1c9d77.mp4
font.8aa31e.woff2

Хеш генерируется на основе содержимого, а не исходного имени.

Разрешение путей и import.meta.url

Помимо прямого импорта, Parcel поддерживает стандартный механизм URL-резолвинга через import.meta.url.

const imageUrl = new URL('./assets/photo.jpg', import.meta.url);

const img = document.createElement('img');
img.src = imageUrl.href;

Такой подход особенно важен при работе с динамическими путями и модульной структурой, где требуется сохранить относительность ресурсов.

Публичная директория и статические файлы

В Parcel существует механизм публичных файлов, которые копируются без трансформации. Такие ресурсы размещаются в специальной директории и доступны по фиксированному пути.

Пример использования:

public/
  robots.txt
  favicon.ico

После сборки:

/dist/robots.txt
/dist/favicon.ico

Эти файлы не участвуют в графе зависимостей и не получают хеширование.

Различие между импортом и статическим ссылочным доступом

Импорт медиа-файла:

import avatar from './avatar.png';

Результат:

  • файл обрабатывается сборщиком;
  • генерируется хешированный URL;
  • учитывается в графе зависимостей.

Статическая ссылка:

<img src="/avatar.png">

Результат:

  • файл не отслеживается сборщиком;
  • отсутствует хеширование;
  • требуется ручное управление путями.

Использование импорта обеспечивает интеграцию с системой сборки и кэширования.

Оптимизация медиа-файлов

Parcel автоматически выполняет ряд оптимизаций:

Сжатие изображений

При включённых оптимизациях изображения проходят через компрессию без потери качества или с заданным уровнем потерь.

Удаление метаданных

EXIF и служебная информация могут удаляться для уменьшения размера.

Разделение по чанкам

Медиа-файлы могут быть вынесены в отдельные чанки, если они используются в динамических импортируемых модулях.

Динамические медиа-импорты

Медиа-файлы могут загружаться лениво через динамический импорт:

async function loadImage() {
  const module = await import('./assets/large-photo.jpg');
  const img = document.createElement('img');
  img.src = module.default;
  document.body.appendChild(img);
}

Такой подход позволяет уменьшить начальный размер бандла.

Поведение в режиме разработки

В режиме разработки Parcel не всегда создаёт физические файлы на диске. Вместо этого:

  • используется dev server;
  • URL указывает на виртуальный ресурс;
  • изменения отражаются мгновенно без пересборки всего проекта.

Пример URL:

http://localhost:1234/logo.png

Поведение в production-сборке

В production-режиме происходит:

  • генерация финальных файлов;
  • хеширование ресурсов;
  • агрессивное кэширование;
  • оптимизация размеров.

Структура выходной директории становится стабильной и предсказуемой.

Обработка видео и аудио

Видео и аудио-файлы рассматриваются как бинарные ресурсы:

import trailer from './media/trailer.mp4';
import click from './media/click.ogg';

const video = document.createElement('video');
video.src = trailer;

Parcel не изменяет содержимое медиа, но обеспечивает корректную доставку и кеширование.

Поведение с SVG

SVG может обрабатываться в нескольких режимах:

  • как URL (строка);
  • как inline-строка;
  • как модуль для манипуляций.
import icon from './icon.svg';

fetch(icon)
  .then(res => res.text())
  .then(svg => {
    document.body.innerHTML += svg;
  });

Взаимодействие с HTML

HTML-файлы также могут ссылаться на медиа-ресурсы, которые обрабатываются Parcel:

<img src="./images/photo.jpg">
<link rel="stylesheet" href="./styles/main.css">

Все пути переписываются на этапе сборки, обеспечивая согласованность структуры проекта.

Интеграция медиа в модульную систему

Главная особенность Parcel заключается в унификации всех типов ресурсов. Медиа-файл становится частью модульной системы, что приводит к следующим эффектам:

  • единый синтаксис импорта;
  • автоматическое управление путями;
  • предсказуемый результат сборки;
  • оптимизация доставки ресурсов.

Такой подход устраняет необходимость ручной работы с папками assets, относительными путями и копированием файлов между окружениями.