При сборке модулей, где одновременно используются ESM (ES Modules) и
CommonJS, возникает задача согласования разных систем экспорта. Rollup
решает её через слой межмодульной совместимости, который управляется
настройкой output.interop.
Этот параметр определяет, как именно будут обрабатываться
default-импорты из CommonJS-модулей и каким образом Rollup
будет генерировать вспомогательный код для согласования типов
экспорта.
ESM и CommonJS по-разному трактуют экспорт:
ESM
default экспортCommonJS
module.exportsdefault не существует как концепцияПри импорте CommonJS-модуля в ESM возникает неоднозначность:
import foo from './cjs-module.cjs';
Что именно считать foo:
module.exports?module.exports.default?Rollup решает это через interop-обёртки.
output.interop в процессе сборкиПараметр output.interop управляет тем, будет ли Rollup
добавлять обёртки совместимости и в каком объёме.
Он влияет на:
__toESM,
__toCommonJS)default импорта из CommonJS__esModule проверкиoutput.interopauto (значение по
умолчанию)Наиболее интеллектуальный режим. Rollup анализирует модуль и добавляет interop только при необходимости.
Поведение:
__esModuleПример поведения:
import foo from 'cjs-lib';
Может быть преобразовано в:
var foo = __toESM(require('cjs-lib'));
или без обёртки, если Rollup уверен в совместимости.
Ключевая особенность:
true (устаревшая форма)Исторически означал включение interop-логики.
Фактически эквивалентен:
autoИспользуется для обратной совместимости конфигураций.
falseПолностью отключает interop-обработку.
Поведение:
default импорт может стать некорректнымПример результата:
import foo from 'cjs-lib';
может превратиться в:
var foo = require('cjs-lib');
Без дополнительной нормализации.
Риски:
defaultРежим, в котором Rollup всегда трактует CommonJS как имеющий
default экспорт.
Поведение:
module.exports считается defaultПример:
import foo from 'cjs-lib';
превращается в:
var foo = require('cjs-lib').default ?? require('cjs-lib');
(логика может варьироваться в зависимости от окружения сборки)
Особенности:
esModuleНаиболее строгий режим интеропа.
Поведение:
__esModule: trueПример:
import foo from 'cjs-lib';
может привести к:
var foo = require('cjs-lib');
без дополнительной нормализации, либо с минимальной обёрткой для соответствия ESM-модели.
Используется в случаях, когда:
__esModuleПри включённом interop Rollup генерирует вспомогательные функции.
__toESMИспользуется для преобразования CommonJS в ESM-совместимую структуру.
Типичное поведение:
default__esModuleПример:
var foo = __toESM(require('cjs-lib'));
__toCommonJSОбратное преобразование:
module.exportsoutput.interop на tree-shakingInterop напрямую влияет на эффективность tree-shaking.
auto:false:default:esModule:Interop не применяется.
Может применяться __toCommonJS.
Основная зона применения output.interop.
Рекомендуется:
autoПозволяет сохранить баланс между совместимостью и размером бандла.
Рекомендуется:
esModuleМинимизирует лишнюю трансформацию.
Рекомендуется:
defaultОбеспечивает стабильный доступ к require()-экспорту.
Возможен вариант:
falseИспользуется для анализа поведения модулей без обёрток.
output.interop тесно связан с:
output.format (esm, cjs, iife)output.exportsoutput.generatedCodeoutput.externalLiveBindingsОсобенно сильная связь наблюдается с форматом esm, где
interop влияет на корректность импортов из CommonJS-зависимостей.
При наличии динамических require():
При сборке Rollup фактически выбирает стратегию:
__esModuleoutput.interopoutput.interop определяет не только синтаксическую
совместимость, но и:
В сложных проектах с большим количеством зависимостей именно этот параметр часто определяет разницу между корректной сборкой и трудноотлавливаемыми ошибками импорта.