Переход с Rollup 2 на Rollup 3

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

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

Среди ключевых направлений развития:

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

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


Основные изменения в Rollup 3

Переход на современные версии Node.js

Одним из первых изменений стало прекращение поддержки старых версий Node.js.

Rollup 2 поддерживал достаточно широкий диапазон версий платформы. Rollup 3 существенно повысил минимальные требования.

Перед обновлением необходимо убедиться, что используемая версия Node.js соответствует требованиям новой версии Rollup.

Типичная последовательность обновления выглядит следующим образом:

node -v
npm install rollup@latest --save-dev

Если сборочная инфраструктура использует CI/CD, Docker-образы или корпоративные серверы, необходимо проверить версии Node.js во всех средах выполнения.


Улучшенная работа с ECMAScript Modules

Rollup всегда позиционировался как инструмент, ориентированный на ESM.

В третьей версии это направление получило дополнительное развитие.

Улучшения затронули:

  • разрешение модулей;
  • обработку экспортов;
  • tree-shaking;
  • динамические импорты;
  • взаимодействие с пакетами npm.

Пример модуля:

export function sum(a, b) {
    return a + b;
}

export function multiply(a, b) {
    return a * b;
}

Если используется только одна функция:

import { sum } from './math.js';

console.log(sum(2, 3));

Rollup 3 эффективнее исключает неиспользуемые части кода из итогового бандла.


Изменения в поведении tree-shaking

Tree-shaking является одной из важнейших функций Rollup.

В версии 3 были улучшены алгоритмы анализа зависимостей и побочных эффектов.

Рассмотрим пример:

export const version = '1.0.0';

export function debug() {
    console.log('debug');
}

export function start() {
    return true;
}

При использовании только функции:

import { start } from './app.js';

start();

Rollup 3 чаще способен полностью удалить:

version
debug

из итоговой сборки.

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


Изменение обработки предупреждений

Система предупреждений была переработана.

Многие сообщения стали:

  • более информативными;
  • лучше структурированными;
  • удобнее для автоматической обработки.

Пример перехвата предупреждений:

export default {
    onwarn(warning, warn) {
        if (warning.code === 'CIRCULAR_DEPENDENCY') {
            return;
        }

        warn(warning);
    }
};

Коды предупреждений сохранились, однако отдельные сообщения были уточнены и расширены.


Изменения в API плагинов

Большинство популярных плагинов продолжили работать без изменений.

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

Типичный плагин:

export default function myPlugin() {
    return {
        name: 'my-plugin',

        transform(code, id) {
            return code;
        }
    };
}

После обновления рекомендуется проверить:

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

Особое внимание следует уделить пользовательским плагинам, которые взаимодействуют с графом модулей или используют низкоуровневые возможности сборщика.


Изменения в объекте this в плагинах

Контекст плагина был дополнительно оптимизирован.

Например:

transform(code, id) {
    const moduleInfo = this.getModuleInfo(id);

    return code;
}

Некоторые внутренние свойства контекста стали недоступны или получили новую реализацию.

Если плагин использовал недокументированные возможности Rollup 2, после обновления возможны ошибки выполнения.


Улучшения графа модулей

Rollup строит граф зависимостей между всеми импортируемыми файлами.

В Rollup 3 этот механизм был оптимизирован.

Преимущества:

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

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


Изменения в генерации чанков

Механизм code splitting получил ряд внутренних улучшений.

Пример:

export default {
    input: {
        app: 'src/app.js',
        admin: 'src/admin.js'
    },
    output: {
        dir: 'dist',
        format: 'es'
    }
};

Rollup 3 может создавать несколько иной набор промежуточных чанков по сравнению с Rollup 2.

Это не считается ошибкой.

Главная цель алгоритма — оптимизация размера итоговой сборки и снижение дублирования кода.


Работа с динамическими импортами

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

Пример:

button.addEventListener('click', async () => {
    const module = await import('./analytics.js');

    module.track();
});

Rollup 3 точнее анализирует подобные конструкции и эффективнее формирует отдельные чанки.

Это особенно полезно для:

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

Изменения в выводе CommonJS

Несмотря на ориентацию на ESM, Rollup продолжает поддерживать CommonJS.

Пример:

module.exports = {
    hello() {
        console.log('Hello');
    }
};

После обновления рекомендуется проверить:

  • экспорт функций;
  • экспорт объектов;
  • экспорт классов;
  • совместимость с Node.js.

Особенно это касается библиотек, публикуемых одновременно в форматах:

ESM
CommonJS
UMD

Обновление официальных плагинов

Во время миграции обычно обновляют и плагины.

Например:

npm install @rollup/plugin-node-resolve@latest
npm install @rollup/plugin-commonjs@latest
npm install @rollup/plugin-json@latest

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

Типичная ситуация:

Rollup 3
+
старый плагин
=
ошибка сборки

Поэтому обновление рекомендуется выполнять комплексно.


Изменения в конфигурационных файлах

Большинство конфигураций продолжают работать без изменений.

Классический пример:

export default {
    input: 'src/index.js',
    output: {
        file: 'dist/bundle.js',
        format: 'es'
    }
};

Однако в сложных проектах стоит проверить:

  • пользовательские хуки;
  • обработчики предупреждений;
  • плагины;
  • нестандартные настройки output;
  • дополнительные скрипты сборки.

Обработка внешних зависимостей

Настройка external осталась прежней:

export default {
    external: ['react', 'react-dom']
};

Тем не менее Rollup 3 стал более строго интерпретировать отдельные сценарии разрешения модулей.

Если после обновления появляются ошибки импорта, следует проверить:

external
resolve
alias

а также настройки package.json.


Проверка package.json

Во время миграции особое внимание уделяется полям:

{
    "type": "module",
    "main": "./dist/index.cjs",
    "module": "./dist/index.js",
    "exports": {
        ".": {
            "import": "./dist/index.js",
            "require": "./dist/index.cjs"
        }
    }
}

Rollup 3 теснее взаимодействует с современной системой экспортов Node.js.

Ошибки в конфигурации пакета могут проявляться значительно чаще, чем в старых версиях.


Типичный процесс миграции

Шаг 1. Обновление Rollup

npm install rollup@latest --save-dev

Шаг 2. Обновление плагинов

npm update

или

npm install @rollup/plugin-node-resolve@latest

Шаг 3. Проверка сборки

npx rollup -c

Шаг 4. Анализ предупреждений

Необходимо проверить:

  • новые warning-сообщения;
  • сообщения о зависимостях;
  • циклические зависимости;
  • предупреждения о внешних пакетах.

Шаг 5. Проверка выходных файлов

Следует убедиться в корректности:

  • размеров бандлов;
  • структуры чанков;
  • карты исходников;
  • экспортируемого API библиотеки.

Наиболее распространённые проблемы после обновления

Несовместимые плагины

Ошибка:

Plugin error

Причина:

Старая версия плагина

Решение:

npm update

Ошибки Node.js

Ошибка:

Unexpected token

или

Cannot use import statement outside a module

Причина часто связана с устаревшей версией Node.js.


Изменение структуры чанков

После обновления возможно появление новых файлов:

chunk-A.js
chunk-B.js
chunk-C.js

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


Изменение результатов tree-shaking

В некоторых проектах размер бандла может измениться.

Причины:

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

Преимущества перехода на Rollup 3

После успешной миграции проект получает ряд преимуществ:

  • более высокую производительность сборки;
  • улучшенную работу с современным JavaScript;
  • более эффективный tree-shaking;
  • улучшенную обработку модулей;
  • оптимизированный граф зависимостей;
  • более качественное разделение кода;
  • улучшенную совместимость с современными пакетами npm;
  • актуальную платформу для дальнейших обновлений экосистемы Rollup.

Для большинства проектов переход с Rollup 2 на Rollup 3 является относительно простым процессом, поскольку базовые принципы конфигурации сохранились. Основные сложности обычно связаны не с самим Rollup, а с устаревшими плагинами, пользовательскими расширениями и инфраструктурой сборки, ориентированной на старые версии Node.js. После устранения подобных несовместимостей новая версия обычно обеспечивает более стабильную и производительную сборку без существенных изменений в существующем коде проекта.