Поле output.generatedCode

Поле output.generatedCode управляет тем, какой синтаксис и какие возможности JavaScript Rollup может использовать при генерации итогового бандла. Это низкоуровневая настройка, влияющая не на логику сборки, а на форму генерируемого кода.

Настройка особенно важна в библиотеках, SDK, пакетах для npm, а также в проектах, где требуется строгий контроль над:

  • совместимостью со старыми средами;
  • размером итогового файла;
  • скоростью выполнения;
  • читаемостью выходного кода;
  • особенностями транспиляции;
  • поведением минификаторов;
  • совместимостью с CommonJS и ES-модулями.

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


Базовый синтаксис

export default {
    input: 'src/index.js',

    output: {
        file: 'dist/bundle.js',
        format: 'cjs',

        generatedCode: {
            arrowFunctions: true,
            constBindings: true
        }
    }
};

Структура generatedCode

Поле принимает:

  • строку;
  • объект с настройками.

Строковый режим

generatedCode: 'es2015'

или:

generatedCode: 'es5'

Объектный режим

generatedCode: {
    arrowFunctions: true,
    constBindings: true,
    objectShorthand: true
}

Объектный режим предоставляет максимально тонкий контроль.


Строковые пресеты

Режим es5

generatedCode: 'es5'

Rollup старается генерировать код, совместимый с ES5.

Особенности:

  • отсутствие стрелочных функций;
  • отсутствие const и let;
  • отсутствие сокращённого синтаксиса объектов;
  • отсутствие современных возможностей синтаксиса.

Пример результата:

'use strict';

var value = 10;

function test() {
    return value;
}

Такой режим используется:

  • в старых браузерах;
  • в legacy-сборках;
  • при поддержке Internet Explorer;
  • в окружениях со старым JavaScript-движком.

Режим es2015

generatedCode: 'es2015'

Разрешает Rollup использовать синтаксис ES2015.

Возможны:

  • стрелочные функции;
  • const;
  • сокращённые свойства объектов;
  • более компактный код.

Пример:

const value = 10;

const test = () => value;

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

  • меньший размер бандла;
  • более быстрый runtime;
  • лучшая оптимизация минификаторами;
  • более чистый output.

Объектный формат generatedCode

Поле arrowFunctions

Управляет использованием стрелочных функций.

Включение

generatedCode: {
    arrowFunctions: true
}

Rollup сможет генерировать:

const fn = () => {};

Отключение

generatedCode: {
    arrowFunctions: false
}

Тогда используется классический синтаксис:

var fn = function () {};

Когда Rollup использует стрелочные функции

Rollup генерирует их:

  • во внутренних helper-функциях;
  • в обёртках модулей;
  • в runtime-коде;
  • в proxy-модулях.

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


Влияние на this

Стрелочные функции не имеют собственного this.

Из-за этого Rollup иногда избегает их использования в некоторых местах даже при:

arrowFunctions: true

Например:

(function () {
    console.log(this);
})();

не может быть безопасно заменено на:

(() => {
    console.log(this);
})();

Поле constBindings

Разрешает использование const.

Пример

generatedCode: {
    constBindings: true
}

Результат:

const external = require('lib');

Без этой настройки:

var external = require('lib');

Почему const важен

const помогает:

  • движкам JavaScript лучше оптимизировать код;
  • минификаторам эффективнее анализировать переменные;
  • улучшать tree-shaking downstream-инструментов.

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


Поле objectShorthand

Управляет сокращённым синтаксисом объектов.

Включение

generatedCode: {
    objectShorthand: true
}

Результат:

const obj = {
    value
};

Вместо:

var obj = {
    value: value
};

Влияние на размер бандла

Сокращённый синтаксис:

  • уменьшает output;
  • снижает объём gzip;
  • делает runtime-код компактнее.

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


Поле reservedNamesAsProps

Управляет использованием зарезервированных слов как свойств объекта.

Пример

generatedCode: {
    reservedNamesAsProps: true
}

Rollup сможет генерировать:

obj.default

Вместо:

obj['default']

Совместимость со старыми браузерами

Некоторые старые JS-движки некорректно работают с:

obj.default

если default считается зарезервированным словом.

Поэтому для ES5-совместимости параметр часто отключают:

reservedNamesAsProps: false

Поле symbols

Разрешает использование Symbol.

Пример

generatedCode: {
    symbols: true
}

Rollup может использовать:

Symbol.toStringTag

Например:

Object.defineProperty(exports, Symbol.toStringTag, {
    value: 'Module'
});

Что происходит при отключении

generatedCode: {
    symbols: false
}

Rollup избегает Symbol API.

Это нужно:

  • для старых сред;
  • для ES5-бандлов;
  • при отсутствии полифилов.

Практические конфигурации

Современная библиотека

export default {
    input: 'src/index.js',

    output: {
        file: 'dist/index.js',
        format: 'esm',

        generatedCode: {
            arrowFunctions: true,
            constBindings: true,
            objectShorthand: true,
            reservedNamesAsProps: true,
            symbols: true
        }
    }
};

Подходит для:

  • современных браузеров;
  • Vite;
  • Webpack 5;
  • Node.js 18+;
  • ESM-пакетов.

Legacy-сборка

export default {
    input: 'src/index.js',

    output: {
        file: 'dist/legacy.js',
        format: 'iife',

        generatedCode: {
            arrowFunctions: false,
            constBindings: false,
            objectShorthand: false,
            reservedNamesAsProps: false,
            symbols: false
        }
    }
};

Подходит для:

  • старых браузеров;
  • ES5;
  • старых embedded-движков.

Двойная сборка

Очень распространённый сценарий.

export default [
    {
        input: 'src/index.js',

        output: {
            file: 'dist/index.mjs',
            format: 'esm',
            generatedCode: 'es2015'
        }
    },

    {
        input: 'src/index.js',

        output: {
            file: 'dist/index.legacy.js',
            format: 'iife',
            generatedCode: 'es5'
        }
    }
];

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

Важное различие

generatedCode влияет только на код, генерируемый самим Rollup.

Он не транспилирует пользовательский код.

Например:

const fn = () => {};

в исходниках останется стрелочной функцией, даже если:

generatedCode: 'es5'

Типичная ошибка

Многие ожидают, что Rollup автоматически превратит весь проект в ES5.

Но:

generatedCode: 'es5'

не заменяет Babel.


Правильная схема

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

export default {
    input: 'src/index.js',

    plugins: [
        babel({
            babelHelpers: 'bundled'
        })
    ],

    output: {
        file: 'dist/bundle.js',
        format: 'iife',
        generatedCode: 'es5'
    }
};

Влияние на размер бандла

ES2015 почти всегда компактнее

Современный синтаксис:

  • короче;
  • лучше минифицируется;
  • эффективнее gzip-сжимается.

Пример

ES5:

var obj = {
    value: value
};

ES2015:

const obj = { value };

Минификаторы любят современный синтаксис

Инструменты:

  • Terser
  • esbuild
  • SWC

лучше оптимизируют ES2015-код.

Особенно:

  • dead code elimination;
  • inline optimization;
  • constant folding.

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

Современный output иногда быстрее:

  • const помогает JIT;
  • стрелочные функции компактнее;
  • сокращённые объекты проще анализировать.

Однако разница обычно невелика.

Главное преимущество — размер и оптимизация.


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

esm

Наиболее естественный формат для:

generatedCode: 'es2015'

cjs

Даже CommonJS может использовать:

  • const;
  • стрелочные функции;
  • shorthand syntax.

iife

Часто используется для браузеров.

Здесь важно учитывать целевую совместимость.


umd

При создании универсальных библиотек часто делают:

generatedCode: 'es5'

чтобы избежать проблем у потребителей пакета.


Внутренние helper-функции Rollup

Rollup генерирует:

  • namespace helpers;
  • interop helpers;
  • export wrappers;
  • live binding runtime.

Именно эти части сильнее всего зависят от generatedCode.


Пример interop helper

Современный вариант:

const getDefaultExportFromCjs = x =>
    x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default')
        ? x['default']
        : x;

ES5-вариант:

function getDefaultExportFromCjs(x) {
    return x &&
        x.__esModule &&
        Object.prototype.hasOwnProperty.call(x, 'default')
            ? x['default']
            : x;
}

Когда стоит использовать es5

Библиотеки для старых проектов

Например:

  • старые корпоративные системы;
  • старые CMS;
  • legacy SPA;
  • встроенные браузеры;
  • Smart TV;
  • старые Android WebView.

Публичные npm-библиотеки

Иногда библиотека должна быть максимально совместимой.

Тогда:

generatedCode: 'es5'

снижает риск проблем.


Когда лучше es2015

Современные frontend-проекты

Например:

  • Vite
  • Next.js
  • Nuxt
  • SvelteKit

ориентированы на современные среды.


Серверный Node.js

Node.js давно поддерживает:

  • const;
  • стрелочные функции;
  • Symbol;
  • shorthand syntax.

Поэтому ES5 обычно не нужен.


Частые ошибки

Ожидание полной транспиляции

generatedCode не заменяет Babel.


Смешивание incompatible output

Например:

generatedCode: 'es2015'

и поддержка IE11.

Это приведёт к runtime-ошибкам.


Игнорирование downstream-среды

Библиотека может работать у автора проекта, но ломаться у пользователей со старым toolchain.


Рекомендации для библиотек

ESM-сборка

generatedCode: 'es2015'

UMD/CJS legacy-сборка

generatedCode: 'es5'

Dual package strategy

Современный стандарт:

dist/
 ├─ index.mjs
 ├─ index.cjs
 └─ index.legacy.js

С разными вариантами generatedCode.


Совместимость с TypeScript

TypeScript также не зависит напрямую от generatedCode.

Например:

const value: number = 10;

сначала компилируется TypeScript-компилятором, а затем Rollup управляет только своим runtime-кодом.


Поведение при tree-shaking

Современный синтаксис улучшает итоговую оптимизацию.

Особенно:

  • const;
  • shorthand syntax;
  • arrow functions.

Минификаторы лучше понимают неизменяемые конструкции.


Связь с output.compact

compact уменьшает количество пробелов и переносов.

generatedCode управляет самим синтаксисом.

Они часто используются вместе:

output: {
    compact: true,
    generatedCode: 'es2015'
}

Связь с output.minifyInternalExports

Современный синтаксис помогает Rollup эффективнее минимизировать внутренние экспорты.

Особенно в ESM-режиме.


Особенности Symbols

При:

symbols: true

Rollup генерирует более корректные namespace-объекты.

Но:

  • старые среды требуют полифилов;
  • некоторые legacy runtime не поддерживают Symbol вообще.

Итоговая стратегия настройки

Максимальная совместимость

generatedCode: 'es5'

Современный frontend

generatedCode: 'es2015'

Тонкая ручная настройка

generatedCode: {
    arrowFunctions: true,
    constBindings: true,
    objectShorthand: false,
    reservedNamesAsProps: true,
    symbols: true
}

Такой подход применяется в крупных библиотеках, где требуется точный контроль над поведением итогового runtime-кода.