@rollup/plugin-dynamic-import-vars

Динамические импорты в формате import() позволяют загружать модули на лету, разделяя приложение на чанки. В стандартной сборке Rollup подобные выражения требуют статического анализа, поскольку сборщик должен заранее понимать структуру графа зависимостей. Однако на практике часто встречаются конструкции, где путь к модулю формируется динамически — через шаблонные строки, переменные или параметры функций.

Проблема возникает в момент, когда Rollup не может определить конкретный файл на этапе анализа:

const module = await import(`./modules/${name}.js`);

Без дополнительной обработки такой код считается недетерминированным, и Rollup не способен построить корректное разбиение на чанки.

Назначение @rollup/plugin-dynamic-import-vars

Плагин @rollup/plugin-dynamic-import-vars расширяет возможности Rollup по анализу динамических импортов, где путь к модулю содержит переменные части. Основная задача — преобразование шаблонных выражений в набор потенциально возможных импортов, чтобы сборщик мог включить их в граф зависимостей.

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

Механизм трансформации

Плагин анализирует вызовы import() и ищет конструкции вида:

  • шаблонные строки с подстановками ${}
  • простые конкатенации строк
  • ограниченные выражения с переменными, которые можно вывести в список вариантов

Пример исходного кода:

const page = await import(`./pages/${pageName}.js`);

После обработки Rollup получает набор возможных модулей:

./pages/home.js
./pages/about.js
./pages/contact.js

и формирует соответствующие чанки заранее.

Ограничения анализа

Поддерживаются только предсказуемые шаблоны. Следующие случаи считаются некорректными для статического анализа:

  • произвольные вычисления внутри пути
  • использование функций в выражении импорта
  • динамические значения, не имеющие ограниченного множества
  • сложные условия внутри строки импорта

Пример неподдерживаемого кода:

const module = await import(`./${getPath()}.js`);

или

const module = await import(`./${a + b + c}.js`);

В таких случаях Rollup не может построить карту зависимостей, и поведение становится неопределённым.

Конфигурация плагина

Подключение осуществляется через конфигурационный файл Rollup:

import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';

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

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

Основные опции

  • warnOnError — управление поведением при невозможности разрешить импорт
  • include — ограничение файлов, к которым применяется трансформация
  • exclude — исключение отдельных модулей из обработки

Пример:

dynamicImportVars({
  warnOnError: true,
  include: 'src/**',
  exclude: 'src/vendor/**'
});

Работа с шаблонами путей

Наиболее распространённый сценарий использования — маршрутизация модулей по имени файла.

export async function loadView(view) {
  return import(`./views/${view}.js`);
}

Плагин преобразует подобные выражения в набор статически известных импортов. Это позволяет Rollup:

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

Использование с условной логикой

Допускается ограниченная форма условных выражений, если они не нарушают статическую природу анализа.

const module = await import(
  condition
    ? `./features/featureA.js`
    : `./features/featureB.js`
);

В этом случае Rollup строит две ветки зависимостей и включает оба модуля в сборку, несмотря на то, что на этапе выполнения используется только один из них.

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

Плагин напрямую влияет на механизм разделения кода. Rollup использует результат анализа для формирования отдельных чанков:

  • каждый возможный импорт становится отдельной точкой входа
  • общие зависимости выносятся в shared chunks
  • динамические точки импорта превращаются в асинхронные границы разделения

Это позволяет строить более предсказуемую архитектуру загрузки приложения.

Обработка каталогов модулей

Часто используется паттерн с модульной структурой папок:

/features
  auth.js
  profile.js
  dashboard.js

Код:

export async function loadFeature(name) {
  return import(`./features/${name}.js`);
}

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

Поведение при ошибках

Если выражение импорта невозможно разрешить, возможны два сценария:

  • предупреждение во время сборки
  • ошибка, прерывающая процесс сборки

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

Совместимость с другими плагинами

@rollup/plugin-dynamic-import-vars часто используется совместно с:

  • плагинами обработки TypeScript
  • плагинами Babel
  • системами alias-резолвинга
  • плагинами для виртуальных модулей

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

Практическое поведение в ESM-бандлах

В итоговой сборке динамические импорты остаются асинхронными точками разделения:

import("./chunk.js").then(...)

или

const mod = await import("./chunk.js");

Rollup гарантирует, что каждый потенциальный модуль будет включён в итоговую структуру чанков и доступен во время выполнения.

Особенности tree-shaking при динамических импортах

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

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

Влияние на производительность сборки

Использование анализа динамических импортов увеличивает нагрузку на этап построения графа зависимостей:

  • требуется обход файловой системы
  • анализируются шаблонные строки
  • формируется расширенный набор зависимостей

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

Типичные архитектурные паттерны

Чаще всего плагин применяется в следующих структурах:

  • модульные UI-системы с ленивой загрузкой компонентов
  • роутинг по страницам в SPA
  • feature-based архитектура
  • плагинные системы с динамическим подключением модулей

Во всех случаях ключевая цель — сохранить динамику загрузки при сохранении статической сборочной модели Rollup.