В экосистеме современного JavaScript сборщик Rollup и статический анализатор кода ESLint решают разные, но взаимодополняющие задачи. Rollup отвечает за упаковку модулей в оптимизированные бандлы, а ESLint обеспечивает контроль качества исходного кода до этапа сборки. Их совместная работа формирует многоуровневую систему проверки, где ошибки выявляются как на уровне синтаксиса и стиля, так и на уровне архитектурных соглашений.
ESLint интегрируется в пайплайн Rollup не как часть трансформации кода, а как промежуточный шаг анализа. Это позволяет предотвращать попадание проблемного кода в процесс бандлинга, снижая вероятность появления дефектов в продакшн-сборке.
Существует несколько подходов к использованию ESLint вместе с Rollup:
Каждая модель выбирается в зависимости от масштаба проекта, требований к скорости сборки и глубины проверки кода.
Наиболее предсказуемая архитектура — запуск ESLint как отдельного этапа до Rollup. Такой подход исключает попадание некорректного кода в систему сборки.
Пример скриптов:
{
"scripts": {
"lint": "eslint src",
"build": "npm run lint && rollup -c"
}
}
В этом случае Rollup не запускается, пока ESLint не завершится без ошибок. Это обеспечивает строгую дисциплину качества кода, особенно в проектах с несколькими разработчиками.
Для более тесной интеграции используется плагинный механизм Rollup.
Один из распространённых вариантов —
@rollup/plugin-eslint.
Установка:
npm install -D @rollup/plugin-eslint eslint
Пример конфигурации Rollup:
import eslint from '@rollup/plugin-eslint';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
eslint({
include: ['src/**/*.js'],
exclude: ['node_modules/**'],
throwOnError: true,
throwOnWarning: false
})
]
};
Такой подход позволяет анализировать код прямо в процессе построения графа модулей Rollup. Ошибки ESLint могут прерывать сборку, а предупреждения — лишь фиксироваться в консоли.
Rollup строит граф зависимостей, начиная с entry-point и рекурсивно проходя по импортам. ESLint-плагин подключается на этапе загрузки модулей и анализирует содержимое каждого файла до его включения в бандл.
Важный аспект — порядок выполнения плагинов. ESLint обычно размещается до трансформационных плагинов (Babel, TypeScript), чтобы анализировать исходный код, а не уже транспилированный результат.
Пример:
import eslint from '@rollup/plugin-eslint';
import typescript from '@rollup/plugin-typescript';
export default {
input: 'src/index.ts',
plugins: [
eslint({
include: ['src/**/*.{ts,js}']
}),
typescript()
]
};
При использовании TypeScript возникает вопрос: анализировать исходный
.ts или уже преобразованный код.
Оптимальная схема:
@typescript-eslint/parser анализирует
TypeScript до компиляции@rollup/plugin-typescript выполняет
транспиляциюКонфигурация ESLint:
export default {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended'
]
};
Rollup:
import typescript from '@rollup/plugin-typescript';
import eslint from '@rollup/plugin-eslint';
export default {
input: 'src/main.ts',
plugins: [
eslint({
include: ['src/**/*.ts']
}),
typescript()
]
};
ESLint может стать узким местом при большом количестве модулей. При интеграции в Rollup важно учитывать:
Для оптимизации применяются следующие стратегии:
1. Ограничение области анализа
eslint({
include: ['src/core/**']
})
2. Кэширование результатов линтинга
Некоторые конфигурации ESLint поддерживают кэш:
eslint src --cache
3. Разделение lint и build
Lint выполняется только при изменениях, не блокируя каждый билд Rollup.
В режиме наблюдения ESLint может выполняться либо при каждом изменении файла, либо выборочно.
Rollup watch:
export default {
watch: {
include: 'src/**'
}
};
При интеграции ESLint важно избегать повторного анализа всего проекта при каждом изменении одного файла. Для этого используются стратегии:
В монорепозиториях ESLint и Rollup часто применяются на уровне пакетов. Структура:
packages/
ui/
core/
utils/
Rollup собирает каждый пакет отдельно, а ESLint работает либо глобально, либо на уровне пакета.
Пример глобального lint:
eslint "packages/**/src"
Rollup-конфигурации при этом изолированы, но используют единый набор правил ESLint через shared config:
module.exports = {
extends: ['../. ./eslint.base.js']
};
Современный формат ESLint Flat Config упрощает интеграцию в сборочные системы.
Пример:
export default [
{
files: ['src/**/*.js'],
rules: {
semi: ['error', 'always']
}
}
];
В связке с Rollup это снижает накладные расходы на парсинг конфигурации и ускоряет старт сборки.
Поведение сборки при ошибках ESLint определяется настройками плагина:
throwOnError: true — остановка сборкиthrowOnError: false — продолжение сборки с выводом
ошибокСтрогий режим:
eslint({
throwOnError: true
})
Мягкий режим:
eslint({
throwOnError: false,
throwOnWarning: false
})
В производственных сборках обычно применяется строгий режим, тогда как в разработке допускается более мягкая политика.
ESLint выполняет статический анализ:
Rollup выполняет:
Пересечение зон ответственности отсутствует, что делает их комбинацию устойчивой к усложнению проекта.
В сложных пайплайнах Rollup может включать несколько стадий:
Пример цепочки:
plugins: [
eslint(),
typescript(),
babel({ babelHelpers: 'bundled' })
]
Порядок влияет на корректность анализа и производительность.
Частые проблемы интеграции:
Каждая из этих проблем приводит к замедлению или нестабильности сборочного процесса.
Совместное использование ESLint и Rollup формирует слой контроля качества, встроенный в процесс сборки. ESLint фиксирует поведенческие и стилистические отклонения на уровне исходников, Rollup обеспечивает детерминированную сборку модульного графа, а их связка позволяет поддерживать предсказуемость результата при росте сложности проекта.