@rollup/plugin-url

Плагин @rollup/plugin-url предназначен для работы с файловыми ресурсами внутри сборки Rollup, позволяя импортировать изображения, шрифты, медиафайлы и другие бинарные данные напрямую в JavaScript-код. Основная идея заключается в том, чтобы либо инлайнить файл в виде data URL, либо вынести его в отдельный файл с генерацией корректного URL для доступа в итоговой сборке.

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


Основная концепция работы плагина

Плагин перехватывает import-запросы к файловым ресурсам и преобразует их в один из двух форматов:

  • Data URL (base64 или UTF-8) — если файл меньше заданного порога
  • Отдельный файл в выходной директории — если размер превышает лимит

Пример поведения:

import logo fr om './logo.png';

В зависимости от настроек результат может быть:

const logo = "data:image/png;base64,iVBORw0KGgoAAA...";

или

const logo = "/assets/logo.hash.png";

Установка

npm install @rollup/plugin-url --save-dev

или

yarn add @rollup/plugin-url -D

Базовая интеграция в Rollup

import url fr om '@rollup/plugin-url';

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm'
  },
  plugins: [
    url()
  ]
};

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


Основные параметры конфигурации

limit

Ключевой параметр, определяющий порог инлайнинга.

url({
  lim it: 8192
});

Логика:

  • файл ≤ 8192 байт → data URL
  • файл > 8192 байт → отдельный файл

Если установить limit: 0, инлайнинг отключается полностью. Если limit: Infinity, все файлы будут встроены.


include и exclude

Позволяют ограничить набор обрабатываемых файлов.

url({
  include: ['**/*.png', '**/*.svg'],
  exclude: ['**/icons/*.svg']
});

Используется glob-логика, что делает фильтрацию гибкой и предсказуемой.


fileName

Определяет шаблон имени выходного файла.

url({
  fileName: 'assets/[name]-[hash][extname]'
});

Поддерживаются плейсхолдеры:

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

Это важно для кеширования и предотвращения конфликтов имен.


sourceDir

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

url({
  sourceDir: path.join(__dirname, 'src/assets')
});

Позволяет корректно сохранять структуру каталогов в выходной сборке.


publicPath

Контролирует базовый URL для файлов, вынесенных в сборку.

url({
  publicPath: '/static/'
});

В результате:

"/static/logo.png"

Используется при деплое на CDN или отдельный static server.


Поведение с различными типами файлов

Изображения

import img fr om './image.png';
  • PNG, JPG, GIF, WebP обрабатываются как бинарные ресурсы
  • могут быть инлайнены или вынесены

SVG

SVG может быть обработан двумя способами:

  1. как строка data URL
  2. как файл
import icon from './icon.svg';

При инлайне:

const icon = "data:image/svg+xml;base64,...";

Шрифты

import font from './font.woff2';

Чаще всего шрифты выносятся в отдельные файлы, так как их размер превышает лимиты инлайна.


Механизм генерации data URL

При инлайнинге происходит:

  1. чтение файла как Buffer
  2. определение MIME-типа по расширению
  3. кодирование в base64
  4. формирование строки:
data:[mime];base64,[data]

Этот механизм делает ресурс независимым от файловой системы.


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

При работе с TypeScript необходимо объявить модули ресурсов:

declare module '*.png' {
  const src: string;
  export default src;
}
declare module '*.svg' {
  const src: string;
  export default src;
}

Это позволяет избежать ошибок компиляции при импортировании файлов.


Сценарии использования

1. UI-ассеты

Иконки, логотипы, небольшие изображения:

import icon from './icon.svg';

При маленьком размере инлайнинг уменьшает количество HTTP-запросов.


2. Критические изображения

Изображения, нужные на первом экране, могут быть встроены:

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

3. Шрифты

Чаще выносятся в файлы, но иногда инлайнятся для уменьшения задержек FOIT.


Взаимодействие с другими плагинами Rollup

image plugins

Если используются плагины вроде @rollup/plugin-image, важно учитывать порядок:

  • url может перехватить импорт раньше
  • конфигурация влияет на приоритет обработки

terser и минификация

@rollup/plugin-url работает до минификации, так как:

  • data URL уже является строкой
  • отдельные файлы не требуют трансформации

typescript plugin

При использовании @rollup/plugin-typescript:

  • сначала TS трансформирует код в JS
  • затем url обрабатывает импорт ресурсов

Особенности работы с хешированием

При использовании [hash] важно понимать:

  • хеш зависит от содержимого файла
  • изменение файла приводит к новому имени
  • это обеспечивает cache busting

Пример:

url({
  fileName: '[name].[hash][extname]'
});

Результат:

logo.a8f3c2.png

Ограничения и нюансы

1. Размер bundle

Чрезмерный инлайнинг увеличивает размер JS-бандла, что может ухудшить:

  • время загрузки
  • время парсинга

2. Memory usage

Инлайнинг больших файлов:

  • увеличивает потребление памяти при сборке
  • может замедлить процесс bundling

3. MIME-тип

Автоматическое определение MIME не всегда идеально:

  • редкие расширения могут требовать ручной настройки
  • при ошибке браузер может некорректно интерпретировать ресурс

Практическая архитектура использования

Типичная конфигурация для продакшена:

url({
  lim it: 4096,
  fileName: 'assets/[name].[hash][extname]',
  publicPath: '/static/',
  include: ['**/*.{png,jpg,jpeg,svg,woff2}']
});

Такой подход:

  • инлайнит только мелкие ресурсы
  • выносит тяжелые файлы
  • обеспечивает кеширование
  • централизует управление ассетами

Важный принцип применения

@rollup/plugin-url эффективно работает там, где ресурсы становятся частью графа модулей, а не внешней системой загрузки. Он позволяет унифицировать работу с файлами, но требует контроля за балансом между инлайнингом и файловым выводом, поскольку это напрямую влияет на производительность конечного приложения и структуру бандла.