Проблемы с путями к файлам

Библиотека Lottie Web отображает анимации на основе JSON-описания, экспортированного из After Effects через Bodymovin. Основная сложность при работе с путями к файлам возникает из-за того, что сам JSON не содержит «исполняемых» ссылок — он хранит строковые пути к ресурсам, которые интерпретируются уже в браузере.

Чаще всего сбои проявляются в трёх формах: отсутствующие изображения, не загружаемые шрифты и некорректное отображение SVG-слоёв. Во всех случаях причина сводится к несоответствию ожидаемой и фактической структуры каталогов.


Как Lottie интерпретирует пути к ресурсам

Внутри экспортированного JSON присутствует секция assets, где каждый элемент описывает внешний ресурс:

  • изображения (p: путь к PNG/JPG)
  • SVG-фрагменты
  • данные для прекомпозиций

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

{
  "assets": [
    {
      "id": "image_0",
      "w": 512,
      "h": 512,
      "p": "images/img_0.png",
      "u": ""
    }
  ]
}

Поле p является относительным путём, а u — базовым префиксом. Именно комбинация этих значений формирует итоговый URL.

Критическая особенность заключается в том, что Lottie Web не «угадывает» структуру проекта и не адаптирует пути под сборщик.


Проблема относительных путей

Наиболее частая ошибка возникает при переносе JSON в другое окружение:

  • локальная папка images/ существует в экспорте
  • в продакшене файлы лежат в /static/lottie/images/

В результате браузер пытается загрузить:

/images/img_0.png

вместо:

/static/lottie/images/img_0.png

Это приводит к 404-ошибкам и пустым слоям анимации.


Базовый путь (public path) и его влияние

При использовании серверов разработки и сборщиков (Webpack, Vite, Parcel) важную роль играет базовый URL приложения.

Если приложение развернуто не в корне домена, например:

https://site.com/app/

то относительные пути из JSON начинают ломаться, так как браузер резолвит их относительно /app/, а не ожидаемой директории.

Типичный результат:

  • изображения не загружаются
  • JSON загружается корректно
  • анимация отображается частично

Решение через assetsPath и модификацию загрузки

В Lottie Web предусмотрен механизм переопределения пути к ресурсам через параметры загрузки.

При использовании loadAnimation корректировка осуществляется через path или через изменение структуры JSON перед передачей:

lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: '/animations/data.json'
});

Однако path влияет только на сам JSON, а не на внутренние assets. Поэтому при наличии изображений требуется корректировать JSON:

animationData.assets.forEach(asset => {
  asset.u = '/static/lottie/';
});

После этого итоговый путь формируется как:

/static/lottie/ + images/img_0.png

Ошибки сборщиков (Webpack, Vite)

При работе с модульными сборщиками проблема усложняется тем, что JSON может импортироваться как модуль:

import animationData from './anim.json';

В этом случае:

  • пути внутри JSON остаются без изменений
  • файлы изображений не попадают в билд автоматически
  • отсутствует синхронизация между assets и output directory

Особенно часто это проявляется при использовании:

  • asset hashing
  • переноса файлов в dist/
  • оптимизации изображений

Конфликт имен и хеширование файлов

Сборщики могут переименовывать изображения:

img_0.png → img_0.8d31f.png

Но JSON остаётся неизменным:

"p": "images/img_0.png"

В результате возникает несоответствие, которое невозможно отследить без проверки итоговой сборки.

Решения включают:

  • отключение хеширования для Lottie-ассетов
  • копирование файлов без трансформации
  • генерацию JSON после сборки

Проблемы при работе через file://

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

Типичные симптомы:

  • JSON загружается нестабильно
  • изображения блокируются
  • консоль показывает CORS-ошибки

Причина заключается в политике безопасности origin-null, при которой относительные пути не имеют корректного контекста.


Кодировка путей и спецсимволы

Пути внутри JSON чувствительны к URL-энкодингу. Частые ошибки:

  • пробелы в именах файлов
  • кириллица без кодировки
  • символы #, %, ?

Пример некорректного пути:

images/my icon.png

Браузер интерпретирует его как:

images/my

и обрезает часть строки.

Корректная форма:

images/my%20icon.png

CORS и внешние CDN

При размещении JSON или ассетов на сторонних доменах возникает ограничение cross-origin.

Если JSON загружается с:

cdn.example.com/anim.json

а изображения с:

assets.example.com/img.png

без корректных заголовков CORS загрузка блокируется.

В Lottie Web это проявляется как «пустая» анимация без явных ошибок в DOM, только сетевые ошибки в консоли.


Несоответствие структуры экспортированной папки

Экспорт Bodymovin обычно создаёт структуру:

animation.json
images/
  img_0.png
  img_1.png

При переносе часто нарушается правило сохранения относительных путей:

  • images выносится отдельно
  • JSON помещается в другую директорию
  • структура flatten-ится

Любое отклонение от исходной схемы приводит к разрыву связей между assets и файловой системой.


Закэшированные пути и обновление ресурсов

Браузер активно кеширует изображения, особенно при повторных загрузках Lottie-анимаций.

Ситуация возникает, когда:

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

Это создаёт эффект «необновляемой» анимации.


Ошибки при динамической подгрузке JSON

При загрузке анимации через fetch или axios JSON может приходить с изменёнными путями из-за:

  • серверной трансформации
  • минификации
  • CDN оптимизации

Пример:

fetch('/anim.json')
  .then(res => res.json())

Если сервер возвращает модифицированный JSON, структура assets перестаёт соответствовать фактическим файлам.


Итоговая природа проблемы путей

Все проблемы с путями в Lottie Web сводятся к одному принципу: JSON описывает статическую файловую структуру, а реальное окружение почти всегда динамическое.

Несовпадение этих двух слоёв — описание и реального размещения файлов — и формирует основную массу ошибок загрузки ресурсов.