@rollup/plugin-alias

@rollup/plugin-alias относится к классу утилитарных плагинов Rollup, которые изменяют поведение резолвинга модулей на этапе сборки. Его основная задача — переопределение путей импорта через систему псевдонимов (aliases), что позволяет упростить структуру импортов, избавиться от относительных путей вида ../. ./. ./ и централизовать управление логикой модульных ссылок.

Rollup строит граф зависимостей, начиная с входной точки, и последовательно разрешает все импортируемые модули. На этапе resolution происходит преобразование строк импортов в реальные пути файловой системы или пакетов.

Стандартный механизм разрешения:

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

Однако в реальных проектах этого недостаточно. При росте кодовой базы появляются:

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

Плагин @rollup/plugin-alias вводит уровень абстракции над resolution, позволяя заменять части пути на заранее заданные алиасы.

Принцип работы alias-резолвера

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

Логика работы можно представить следующим образом:

  1. Rollup встречает импорт:

    import Button from '@ui/button';
  2. Plugin alias проверяет список правил:

    '@ui': 'src/components/ui'
  3. Происходит подмена:

    @ui/button → src/components/ui/button
  4. Rollup продолжает стандартный процесс resolution уже с новым путём.

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

Установка и подключение

Плагин является официальным дополнением Rollup и устанавливается отдельно.

Базовая установка:

npm install @rollup/plugin-alias -D

Подключение в конфигурации Rollup:

import alias from '@rollup/plugin-alias';

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

Конфигурационная модель entries

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

Базовая структура

{
  find: string | RegExp,
  replacement: string
}

Пример с несколькими алиасами

alias({
  entries: [
    { find: '@', replacement: './src' },
    { find: '@api', replacement: './src/api' },
    { find: '@utils', replacement: './src/utils' },
    { find: '@components', replacement: './src/components' }
  ]
})

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

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

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

Пример:

alias({
  entries: [
    {
      find: /^@shared\/(.*)/,
      replacement: 'src/shared/$1'
    }
  ]
});

Здесь $1 используется как захватывающая группа, позволяя динамически переносить часть пути.

Это особенно полезно при:

  • масштабных монорепозиториях
  • миграции структуры проекта
  • унификации старых и новых путей

Поведение при конфликте правил

Порядок объявления entries имеет значение. Rollup проверяет правила последовательно, и первое совпадение считается финальным.

Пример:

entries: [
  { find: '@', replacement: './src' },
  { find: '@utils', replacement: './src/utils' }
]

Импорт:

import x from '@utils/math';

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

Корректная организация:

  • сначала специфичные алиасы (@utils)
  • затем общие (@)

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

@rollup/plugin-alias работает совместно с:

  • @rollup/plugin-node-resolve
  • TypeScript path mapping (частично)
  • Babel plugins (косвенно)

Типичный порядок плагинов:

plugins: [
  alias({ entries: [...] }),
  nodeResolve(),
  commonjs()
]

Причина такого порядка — alias должен сработать до того, как node-resolve начнёт искать модули в node_modules.

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

TypeScript имеет собственную систему алиасов через compilerOptions.paths, но она не влияет на Rollup напрямую.

Пример tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Rollup не читает эти настройки автоматически, поэтому требуется дублирование конфигурации:

alias({
  entries: [
    { find: '@', replacement: './src' }
  ]
})

При необходимости синхронизации используют:

  • ручное дублирование
  • генерацию конфигурации
  • плагины синхронизации (внешние решения)

Поддержка абсолютных и относительных путей

Alias может работать как с абсолютными, так и с относительными путями.

Относительный вариант

{ find: '@', replacement: './src' }

Абсолютный вариант (через path.resolve)

import path from 'path';

alias({
  entries: [
    {
      find: '@',
      replacement: path.resolve(__dirname, 'src')
    }
  ]
});

Абсолютные пути уменьшают риск ошибок при запуске сборки из разных директорий.

Типичные сценарии использования

Централизация импортов

import api from '@api/client';
import Button from '@components/Button';

Вместо:

import api from '../. ./api/client';
import Button from '../components/Button';

Упрощение рефакторинга

При изменении структуры проекта достаточно обновить alias:

{ find: '@components', replacement: './src/ui/components' }

без правок во всех файлах.

Изоляция слоёв архитектуры

В архитектурах типа layered architecture или clean architecture alias помогает разделять уровни:

  • @domain
  • @application
  • @infrastructure

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

Несмотря на простоту, есть ряд ограничений:

  • не выполняет анализ содержимого модулей
  • не проверяет существование файлов
  • не синхронизируется автоматически с TypeScript
  • не влияет на runtime, только на build-time resolution
  • не поддерживает сложную логику условий кроме RegExp

Поведение при отсутствии совпадений

Если импорт не совпадает ни с одним правилом, он передаётся дальше в стандартный механизм Rollup без изменений.

import x from 'some-package';

Если some-package не входит в alias-правила, обработка полностью делегируется node-resolve.

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

В монорепозиториях alias часто используется для связки пакетов:

alias({
  entries: [
    { find: '@app', replacement: '../app/src' },
    { find: '@shared', replacement: '../shared/src' }
  ]
})

Это позволяет:

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

Диагностика и отладка

При работе с alias важно учитывать, что ошибки чаще всего связаны не с самим плагином, а с резолвингом путей.

Типичные проблемы:

  • неверный base path
  • конфликтующие правила
  • отсутствие node-resolve после alias
  • несовпадение структуры проекта и replacement

Для диагностики полезно:

  • проверять итоговый resolved path через verbose-логи Rollup
  • временно упрощать конфигурацию до одного правила
  • исключать RegExp при отладке

Производственные практики конфигурации

Структурирование alias-конфигурации в крупных проектах обычно выносится в отдельный модуль:

export const aliases = [
  { find: '@', replacement: './src' },
  { find: '@api', replacement: './src/api' },
  { find: '@shared', replacement: './src/shared' }
];

И подключается:

import alias from '@rollup/plugin-alias';
import { aliases } from './build/aliases.js';

export default {
  plugins: [
    alias({ entries: aliases })
  ]
};

Такой подход снижает связность конфигурации сборки и упрощает масштабирование.