Введение в сборщик JavaScript Rollup.js

Rollup.js - это сборщик модулей Node.js, наиболее часто используемый для клиентского JavaScript, выполняемого в браузере. (Вы можете объединить сценарии Node.js, но причин для этого меньше). Инструмент компилирует все ваши исходные файлы JavaScript в единый пакет для включения в ваши рабочие веб-страницы.

Преимущества использования Rollup.js:

  1. Вы можете разрабатывать JavaScript в небольших автономных файлах, которые имеют определенные обязанности. Проект становится проще для понимания и поддержки.
  2. Он включает в себя опцию просмотра, которая повторно запускает связывание всякий раз, когда вы вносите изменения в исходный файл.
  3. Rollup.js может проверять исходный код (линтинг), реструктурировать макет (prettify) и выполнять другие проверки синтаксиса.
  4. Неиспользуемые функции автоматически удаляются с помощью методов встряхивания дерева, которые уменьшают размер файлов и повышают производительность.
  5. Из одних и тех же исходных файлов может быть выведено несколько пакетов, например версия ES6 с использованием модулей, версия ES5 для старых браузеров, версия CommonJS для Node.js и т. Д.
  6. В окончательном производственном пакете могут быть удалены пробелы и журнал, чтобы уменьшить размер файла.

Rollup.js имеет некоторую конкуренцию с такими инструментами сборки, как webpack, Snowpack и Parcel. Помимо объединения модулей JavaScript, они могут обрабатывать другие аспекты вашего сайта, такие как шаблоны HTML, предварительную обработку CSS и оптимизацию изображений. Обратной стороной является то, что их сложнее настроить, если у вас есть индивидуальные требования.

Rollup.js в первую очередь ориентирован на JavaScript, поэтому он быстрый и легкий. Начать работу легко, но по мере знакомства с инструментом вы обнаружите плагины для HTML, CSS, изображений и других параметров. Давайте начнем…

Установка Rollup.js

Rollup.js требует Node.js v8.0.0 или выше. Вы можете установить его глобально, запустив:

npm install rollup --global

Затем вы можете выполнить команду rollup из любого каталога проекта.

Вы также можете установить Rollup.js в папку проекта Node.js, используя:

npm install rollup --save-dev

Это управляет установкой в ​​package.json файле npm, чтобы гарантировать, что все разработчики в вашей команде используют одну и ту же версию, чтобы избежать проблем с совместимостью. Вы можете запустить Rollup.js с npx rollup или добавить команды в раздел "scripts" файла package.json, например

"scripts": {
  "rollup:help": "rollup --help"
},

Выполните сценарий с npm run <scriptname>, например npm run rollup:help.

В приведенных ниже примерах используется npx rollup, поскольку он будет работать независимо от того, устанавливаете ли вы rollup локально или глобально.

Первое использование

Создайте папку проекта с подпапкой src и добавьте следующие файлы:

Библиотечные функции в src/a.js:

export function hello() {
  console.log('hello from a.js');
}
export function goodbye() {
  console.log('goodbye from a.js');
}

Библиотечные функции в src/b.js:

export function hello() {
  console.log('hello from b.js');
}
export function goodbye() {
  console.log('goodbye from b.js');
}

Точка входа основного скрипта в src/main.js:

import * as a from './a.js';
import * as b from './b.js';
a.hello();
b.goodbye();

Теперь запустите Rollup.js, чтобы объединить исходные файлы в один файл ES6:

npx rollup ./src/main.js --file ./build/bundle.js --format es

Полученный build/bundle.js файл содержит:

function hello() {
  console.log('hello from a.js');
}
function goodbye() {
  console.log('goodbye from b.js');
}
hello();
goodbye();

Весь ваш код теперь содержится в одном файле, а инструмент удаляет неиспользуемые функции. Вы можете загрузить его из файла HTML, используя:

<script type="module" src="./build/bundle.js"></script>

В этом случае связанный <script> также будет работать в старых браузерах, таких как IE11, если вы удалите атрибут type="module". Добавьте атрибут defer или поместите его перед закрывающим </body>, чтобы сценарий запускался после загрузки DOM.

Попробуйте отредактировать и добавить вызов функции a.goodbye():

import * as a from './a.js';
import * as b from './b.js';
a.hello();
a.goodbye();
b.goodbye();

Снова объедините с помощью команды:

npx rollup ./src/main.js --file ./build/bundle.js --format es

Или добавьте еще "scripts" запись в package.json, например:

"scripts": {
  "rollup:help": "rollup --help",
  "rollup:es": "rollup ./src/main.js --file ./build/bundle.js --format es"
},

и запустить с npm run rollup:es.

Полученный файл build/bundle.js содержит дополнительную переименованную функцию, которая позволяет избежать конфликтов:

function hello() {
  console.log('hello from a.js');
}
function goodbye$1() {
  console.log('goodbye from a.js');
}
function goodbye() {
  console.log('goodbye from b.js');
}
hello();
goodbye$1();
goodbye();

Параметры и флаги Rollup.js

В приведенном выше примере представлены основные параметры командной строки Rollup.js. Наиболее часто используются:

  • --version (или -v): отображение номера версии Rollup.js
  • --input <filename> (или -i): укажите сценарий входа. В этом нет необходимости, потому что файл обычно определяется как первый вариант.
  • --file <output> (или -o): имя связанного файла. Если не указано иное, пакет выводится на stdout.
  • --format <type> (или -f): формат пакета JavaScript:
    iifeoutput выражение немедленно вызываемой функции (function () { ... }());
    es
    standard ES6
    cjsCommonJS для Node.js
    umd Универсальное определение модуля
    amd Асинхронный модуль Определение
    system Модули SystemJS
  • В случае сомнений используйте es6. iife может быть практичным, если вам нужно поддерживать старые браузеры, не поддерживающие модули.
  • --environment <values>: установить одну или несколько переменных среды, разделенных запятыми, например --environment NODE_ENV:development,VAR1,VAR2:abc, который устанавливает NODE_ENV в development, VAR1 в true и VAR2 в abc.
  • --sourcemap: создайте карту источников, чтобы вы могли ссылаться на исходные файлы в браузере DevTools. Связанный файл будет ссылаться на файл .map в папке сборки, например build/bundle.js.map.
  • Используйте --sourcemap inline для определения встроенной исходной карты в пакете.
  • --watch (или -w): следите за изменениями исходного файла во время разработки и объединяйте автоматически.
  • Экран очищается, когда изменение вызывает повторную сборку, но вы можете отключить это с помощью --no-watch.clearScreen
  • --silent: не выводить предупреждения.

Файлы конфигурации Rollup.js

Команды могут стать громоздкими при добавлении параметров и флагов. Конфигурационный файл Rollup.js - лучшая альтернатива:

  1. легче читать и редактировать
  2. вы можете определить более одного пакетного процесса, и
  3. файл конфигурации - это модуль ES6, который может выполнять другие функции. Например, вы можете условно обрабатывать разработки или производственные сборки в соответствии со средой, в которой выполняется Rollup.js.

Имя файла конфигурации по умолчанию - rollup.config.js. Создайте этот файл в корне папки проекта и добавьте следующий код для репликации параметров ввода, вывода и форматирования, использованных выше:

// rollup.config.js
export default [
  {
    input: './src/main.js',
    output: {
      file: './build/bundle.js',
      format: 'es'
    }
  }
];

Установите флаг Rollup.js --config (или -c), чтобы использовать этот файл конфигурации:

npx rollup --config

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

npx rollup --config ./rollup/config1.js

Приведенная выше конфигурация экспортирует массив с одним объектом, который определяет один процесс пакета. Массив не требуется для одного объекта, но он позволяет вам определять дальнейшие процессы позже, например

// rollup.config.js
export default [
  // ES6 bundle
  {
    input: './src/main.js',
    output: {
      file: './build/bundle.js',
      format: 'es'
    }
  },
  // IIFE bundle
  {
    input: './src/main.js',
    output: {
      file: './build/bundle-iife.js',
      format: 'iife'
    }
  }
];

Автоматическое объединение часов

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

// rollup.config.js
export default [
  {
     input: './src/main.js',
     watch: {
      include: './src/**',
      clearScreen: false
    },
    output: {
      file: './build/bundle.js',
      format: 'es'
    }
  }
];

Обратите внимание, что вы все равно должны использовать флаг --watch в командной строке:

npx rollup --config --watch

Создание сборок для разработки и производства

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

Следующая конфигурация проверяет переменную среды NODE_ENV и добавляет в пакет встроенную карту источников, если для нее установлено значение development:

// rollup.config.js
const devMode = (process.env.NODE_ENV === 'development');
console.log(`${ devMode ? 'development' : 'production' } mode bundle`);
export default [
  {
    input: './src/main.js',
    output: {
      file: './build/bundle.js',
      format: 'es',
      sourcemap: devMode ? 'inline' : false
    }
  }
];

Запустите команду Rollup.js с соответствующей установленной переменной окружения:

npx rollup --config --environment NODE_ENV:development

Вы также можете установить NODE_ENV для текущего сеанса в Mac OS и Linux:

NODE_ENV=development

приглашение Windows cmd:

set NODE_ENV=development

или Windows Powershell:

$env:NODE_ENV="development"

Плагины Rollup.js

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

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

Минимизировать производственные пакеты

Terser может уменьшить размер файла пакета, удалив пробелы, комментарии, команды регистрации и другой ненужный код. Установите Rollup.js Terser plugin локально:

npm install rollup-plugin-terser --save-dev

затем импортируйте его в свой rollup.config.js файл и добавьте определение массива plugins к объекту output (Terser - это модуль вывода, который запускается после того, как Rollup.js завершил другие задачи по связыванию):

// rollup.config.js
import { terser } from 'rollup-plugin-terser';
const devMode = (process.env.NODE_ENV === 'development');
console.log(`${ devMode ? 'development' : 'production' } mode bundle`);
export default [
  {
    input: './src/main.js',
    output: {
      file: './build/bundle.js',
      format: 'es',
      sourcemap: devMode ? 'inline' : false,
      plugins: [
        terser({
          ecma: 2020,
          mangle: { toplevel: true },
          compress: {
            module: true,
            toplevel: true,
            unsafe_arrows: true,
            drop_console: !devMode,
            drop_debugger: !devMode
          },
          output: { quote_style: 1 }
        })
      ]
    }
  }
];

Запустите сборку для разработки с помощью:

npx rollup --config --environment NODE_ENV:development

и результирующий файл ./build/bundle.js содержит:

console.log('hello from a.js'),console.log('goodbye from a.js'),console.log('goodbye from b.js');
//# sourceMappingURL=data:application/json;charset=utf-8;base64,...

Производственная сборка приводит к пустому файлу, поскольку Terser удаляет все операторы ведения журнала!

Обратитесь к документации Terser, чтобы настроить собственные параметры проекта.

Заменить значения во время сборки

Заменить плагин Rollup.js позволяет вам определять конфигурационные переменные во время сборки, которые жестко запрограммированы в связанном скрипте. Установите его локально:

npm install @rollup/plugin-replace --save-dev

затем импортируйте его в свой rollup.config.js файл и добавьте массив plugins со следующими настройками:

// rollup.config.js
import replace from '@rollup/plugin-replace';
const devMode = (process.env.NODE_ENV === 'development');
console.log(`${ devMode ? 'development' : 'production' } mode bundle`);
export default [
  {
    input: './src/main.js',
    plugins: [
      replace({
        values: {
          __HELLO__: 'Hi there',
          __GOODBYE__: 'Bye'
        }
      })
    ],
    output: {
      file: './build/bundle.js',
      format: 'es',
      sourcemap: devMode ? 'inline' : false
    }
  }
];

Добавьте токены __HELLO__ и __GOODBYE__ в любом месте ваших скриптов, например:

export function hello() {
  console.log('__HELLO__ from a.js');
}
export function goodbye() {
  console.log('__GOODBYE__ from a.js');
}

Запустите сборку для разработки с помощью:

npx rollup --config --environment NODE_ENV:development

и получившийся файл ./build/bundle.js теперь содержит:

function hello() {
  console.log('Hi there from a.js');
}
function goodbye$1() {
  console.log('Bye from a.js');
}
function goodbye() {
  console.log('goodbye from b.js');
}

Импорт модулей CommonJS из npm

Библиотеки JavaScript часто упаковываются как модули CommonJS, которые можно установить с npm. Rollup.js может анализировать CommonJS с помощью следующих плагинов:

  1. node-resolve находит модуль в каталоге node_modules проекта, и
  2. plugin-commonjs преобразует CommonJS в модули ES6.

Установите их в свой проект:

npm install @rollup/plugin-node-resolve @rollup/plugin-commonjs --save-dev

затем импортируйте их в свой rollup.config.js файл и обновите массив plugins:

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
const devMode = (process.env.NODE_ENV === 'development');
console.log(`${ devMode ? 'development' : 'production' } mode bundle`);
export default [
  {
    input: './src/main.js',
    plugins: [
      nodeResolve(),
      commonjs()
    ],
   output: {
      file: './build/bundle.js',
      format: 'es'
    }
  }
];

Установите пример библиотеки CommonJS, такой как Lodash:

npm install lodash --save-dev

и используйте один из его методов, например capitalize() в:

import * as _ from 'lodash/string';
export function hello() {
  console.log(_.capitalize('hello from a.js '));
}

Запустите сборку для разработки с помощью:

npx rollup --config --environment NODE_ENV:development

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

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

Воспроизведение сеанса с открытым исходным кодом

Отладка веб-приложения в рабочей среде может быть сложной задачей и потребовать много времени. OpenReplay - альтернатива с открытым исходным кодом для FullStory, LogRocket и Hotjar. Он позволяет вам отслеживать и воспроизводить все, что делают ваши пользователи, и показывает, как ваше приложение ведет себя при каждой проблеме. Это похоже на то, как если бы инспектор браузера был открыт, а пользователь смотрит через плечо. OpenReplay - единственная доступная альтернатива с открытым исходным кодом.

Удачной отладки, для современных команд, работающих с веб-интерфейсом - Начни мониторинг своего веб-приложения бесплатно.

Транспилируйте ES6 в ES5 с помощью Babel

Синтаксис ES6 дает более лаконичный код. Например, вы можете использовать выражения стрелочной функции в src/a.js:

const hello = () => {
  console.log('hello from a.js ');
};
const goodbye = () => {
  console.log('goodbye from a.js');
};
export { hello, goodbye };

Полученный пакет будет работать во всех современных браузерах, но не работать в устаревших приложениях, таких как Internet Explorer 11 и ниже. Это может не вызывать беспокойства: IE11 имеет минимальную долю рынка, и эти пользователи все еще могут видеть контент, если ваш сайт достаточно хорошо работает без JavaScript.

Вы можете перенести свой код в ES5 с помощью Babel, если вам не повезло иметь достаточно большое количество пользователей IE11. Полученный код должен работать в любом браузере (хотя вам может потребоваться Polyfills для добавления недостающих функций в IE11).

Объединение двух файлов из одного источника - лучший вариант. Вы можете создать небольшую версию ES6, загружаемую всеми браузерами, которые поддерживают модули ES, и более крупную резервную версию ES5 для старых браузеров.

Установите Babel локально:

npm install @rollup/plugin-babel @babel/core @babel/preset-env --save-dev

затем импортируйте его в свой rollup.config.js файл и добавьте конфигурацию пакета ES5 в экспортированный массив:

// rollup.config.js
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
const devMode = (process.env.NODE_ENV === 'development');
console.log(`${ devMode ? 'development' : 'production' } mode bundle`);
export default [
  {
    // ES6
    input: './src/main.js',
    output: {
      file: './build/bundle.js',
      format: 'es'
    }
  },
  {
    // ES5
    input: './src/main.js',
    plugins: [
      getBabelOutputPlugin({
        presets: ['@babel/preset-env']
      })
    ],
    output: {
      file: './build/bundle-es5.js',
      format: 'cjs'
    }
  }
];

Запустите сборку для разработки с помощью:

npx rollup --config --environment NODE_ENV:development

для создания двух файлов пакета. build/bundle.js содержит код, совместимый с ES6:

const hello = () => {
  console.log('hello from a.js ');
};
const goodbye$1 = () => {
  console.log('goodbye from a.js');
};
function goodbye() {
  console.log('goodbye from b.js');
}
hello();
goodbye$1();
goodbye();

и build/bundle-es5.js содержит код, совместимый с ES5:

'use strict';
var hello = function hello() {
  console.log('hello from a.js ');
};
var goodbye$1 = function goodbye$1() {
  console.log('goodbye from a.js');
};
function goodbye() {
  console.log('goodbye from b.js');
}
hello();
goodbye$1();
goodbye();

Ссылка на оба сценария в любом HTML-файле:

<script type="module" src="./build/bundle.js"></script>
<script nomodule src="./build/bundle-es5.js" defer></script>

Современные браузеры загружают и запускают модуль ES6, содержащийся в ./build/bundle.js. Старые браузеры загрузят и запустят сценарий ES5, содержащийся в ./build/bundle-es5.js. В обоих случаях сценарии будут выполняться, когда DOM будет готов - это значение по умолчанию для ES6, а атрибут defer включает его в ES5.

Прокатывая свой собственный

Rollup.js требует немного больше начальных усилий, чем инструменты сборки, такие как Webpack и Parcel, но текущая настройка проще и гибче. Полученные пакеты должны быть меньше и быстрее.

Для получения дополнительной информации посетите сайт Rollupjs.org. Большой список параметров Rollup.js описывает все параметры командной строки, и вы можете просмотреть потрясающий список плагинов Rollup.js. Вы найдете десятки плагинов для создания и оптимизации HTML, CSS, файлов, изображений, TypeScript, URI данных, качества кода и многого другого. Вы также можете интегрировать Rollup.js с проектами Deno, Grunt, Gulp, React, Angular, Vue и Svelte. Я рекомендую вам сначала сохранить простую конфигурацию, а затем добавлять дополнительные параметры конфигурации по мере расширения ваших знаний о Rollup.js.

Первоначально опубликовано на https://blog.openreplay.com 7 октября 2021 г.