
Привет, Хабр!
Когда-то были времена, когда весь JavaScript-код приложения складывался в один огромный файл. Это было не только неудобно, но и было множество ошибок из-за глобального пространства имен и сложностей с зависимостями. Тогда появилась необходимость в модульности.
Многие при первой встречи с такими проблемами пытались разделить код на отдельные файлы и подключать через тег <script>. Но такое решение было очень далеко от идеала. Потом были попытки использовать различные библиотеки и инструменты, такие как RequireJS или Browserify, но каждый из них имел свои недостатки и ограничения.
Все изменилось с приходом ES6, который ввел нативную поддержку модулей и один из этих модулей — Rollup. Сегодня мы его и рассмотрим в статье.
Установим и настроим
Создадим директорию для проекта и переходим в неё:
mkdir my-rollup-project && cd my-rollup-project
Инициализируем с помощью NPM:
npm init -y
Установим Rollup как зависимость:
npm install rollup --save-dev
Создадим файл rollup.config.js в корневой директории проекта:
export default { input: 'src/main.js', output: { file: 'bundle.js', format: 'cjs' } };
Добавим скрипт сборки в package.json:
"scripts": { "build": "rollup -c" }
Для запуска сборки:
npm run build
Добавление CSS
Для работы с CSS потребуется плагин. Установим rollup-plugin-postcss:
npm install rollup-plugin-postcss --save-dev
Добавим этот плагин в rollup.config.js:
import postcss from 'rollup-plugin-postcss'; export default { input: 'src/index.js', output: { file: 'dist/bundle.js', format: 'iife', }, plugins: [ postcss({ extensions: ['.css'], }), ], };
Теперь можно создать файл стилей styles.css в папке src и импортировать его в index.js:
/* src/styles.css */ body { background-color: #f0f0f0; }
// src/index.js import './styles.css'; console.log('Привет, Хабр!');
Работа с изображениями
Для включения изображений в бандл используем плагин rollup-plugin-img:
Обновим rollup.config.js, добавив этот плагин:npm install rollup-plugin-img --save-dev
Обновим rollup.config.js, добавив этот плагин:
import postcss from 'rollup-plugin-postcss'; import img from 'rollup-plugin-img'; export default { input: 'src/index.js', output: { file: 'dist/bundle.js', format: 'iife', }, plugins: [ postcss({ extensions: ['.css'], }), img({ limit: 10000 // размер файла в байтах для инлайнинга изображений }), ], };
Теперь можно добавить изображение в папку src и использовать его в CSS или JavaScript. Например, в styles.css:
body { background-image: url('./background.png'); background-size: cover; }
Или напрямую в index.js:
import background from './background.png'; document.body.style.backgroundImage = `url('${background}')`;
Также установим некоторые нужные плагины
@rollup/plugin-node-resolve: позволяет Rollup подключать внешние модули из node_modules:
npm install --save-dev @rollup/plugin-node-resolve
Включим в конфигурационный файл:
import resolve from '@rollup/plugin-node-resolve'; export default { //... plugins: [resolve()] };
Абсолютно аналогично можно установить:
@rollup/plugin-commonjs: преобразует модули CommonJS в формат ES6, который может обрабатывать Rollup.
@rollup/plugin-json: позволяет Rollup импортировать данные из JSON-файлов.
@rollup/plugin-babel: интегрирует Babel для транспиляции кода в старые версии JavaScript.
Для Babel нужно будет создать.babelrc с настройками Babel:
{ "presets": [ ["@babel/preset-env", { "modules": false }] ] }
@rollup/plugin-terser: минифицирует итоговый бандл для продакшена.
Основные функции Rollup
Tree-Shaking
Tree-Shaking – это процесс устранения кода, который фактически не используется в проекте.
Tree-Shaking работает, анализируя кодовые файлы, необходимые для запуска приложения, и включая только код, который действительно используется приложением. Этот процесс создаёт структуру данных, представляющую намерения вашего кода, состоящую из узлов, которые представляют код (функции, утверждения и т.д.). Эти узлы формируют структуру, похожую на дерево, и после её создания можно определить, какой код действительно используется приложением .
Tree-Shaking в JS работает благодаря использованию ES6 модулей, потому что они статичны в своей структуре. Каждый файл, проанализированный в процессе Tree-Shaking, будет иметь различные виды операторов экспорта как узел верхнего уровня создаваемой структуры данных. В файлах, которые импортируют эти экспортированные члены, использование импорта может быть отслежено.
Рассмотрим пример использования Tree-Shaking с помощью Rollup, демонстрирующий как неиспользуемый код может быть исключен из итогового бандла.
Предположим, есть два файла модулей: math.js и main.js. В math.js определены несколько функций, но main.js использует только одну из них.
math.js:
export const sum = (a, b) => a + b; export const multiply = (a, b) => a * b; export const subtract = (a, b) => a - b;
main.js:
import { sum } from './math.js'; console.log(sum(1, 2)); // Ожидается вывод: 3
Если мы используем Rollup для сборки, он анализирует зависимости и понимает, что только функция sum используется в main.js. Функции multiply и subtract не используются и, следовательно, могут быть исключены из финального бандла благодаря механизму Tree-Shaking.
Для запуска Tree-Shaking с Rollup, можно юзать следующий конфигурационный файл Rollup rollup.config.js:
export default { input: 'main.js', // точка входа вашего приложения output: { file: 'bundle.js', // имя итогового файла format: 'es' // формат модулей в итоговом бандле } };
Затем, запускаем Rollup с этой конфигурацией, и он сгенерирует bundle.js, содержащий только используемый код. В результате размер итогового файла будет меньше, и приложение загрузится быстрее.
Code Splitting
Code-Splitting позволяет разделить код на разные части на основе различных точек входа и динамических импортов, используя механизм импорта формата вывода вместо пользовательского кода загрузчика . Это позволяет динамически загружать части приложения по мере необходимости.
Для демонстрации Code Splitting с помощью Rollup, рассмотрим пример, где у нас есть две точки входа в приложение и динамический импорт модуля.
Структура проекта:
-
src/-
main1.js(точка входа 1) -
main2.js(точка входа 2) -
shared.js(модуль, используемый обеими точками входа) -
dynamic.js(модуль, импортируемый динамически)
-
shared.js:
// экспортируем функцию, общую для main1.js и main2.js export const sharedFunction = () => console.log('Это общая функция');
dynamic.js:
// экспортируем функцию для динамического импорта export const dynamicFunction = () => console.log('Это динамическая функция');
main1.js:
import { sharedFunction } from './shared.js'; // использование общей функции sharedFunction(); // динамический импорт модуля import('./dynamic.js').then((module) => { module.dynamicFunction(); });
main2.js:
import { sharedFunction } from './shared.js'; // использование общей функции sharedFunction(); // предположим, здесь есть дополнительный код специфичный для main2.js
Для поддержки Code Splitting в Rollup конфигурации нужно определить обе точки входа и настроить выходные параметры для генерации нескольких чанков:
rollup.config.js:
export default { input: ['src/main1.js', 'src/main2.js'], output: { dir: 'output', format: 'esm', chunkFileNames: '[name]-[hash].js' }, plugins: [ // здесь можно юзать плагины, например @rollup/plugin-node-resolve для разрешения модулей из node_modules ] };
input определяется как массив с двумя точками входа. Rollup будет анализировать зависимости, обнаруживать общие модули и динамические импорты, и соответственно разделять код на чанки. В результате, shared.js будет вынесен в отдельный чанк, так как используется обеими точками входа, в то время как dynamic.js будет загружен динамически только при необходимости.
Настройка Rollup для работы с TypeScript, React
Для начала работы с TypeScript и React необходимо установить соответствующие пакеты и зависимости:
npm i --save-dev typescript react react-dom @types/react
Для интеграции TypeScript в проект с Rollup юзаем плагин @rollup/plugin-typescript. Простейший файл конфигурации rollup.config.js может выглядеть так:
import typescript from '@rollup/plugin-typescript'; export default { input: 'src/index.tsx', // точка входа приложения output: { dir: 'dist', // каталог для сгенерированных файлов format: 'esm', // формат модуля ES }, plugins: [typescript()], };
Эта конфигурация указывает Rollup на обработку файлов TypeScript и сборку их в модули ES6.
Файл tsconfig.json содержит настройки компилятора TypeScript. Пример базовой конфигурации:
{ "compilerOptions": { "outDir": "./dist", "module": "ESNext", "target": "es5", "jsx": "react", "declaration": true, "declarationDir": "./dist" }, "include": ["src/**/*"] }
Здесь будет поддержка JSX, генерацию деклараций типов и компиляцию в ES5 для лучшей совместимости.
Для работы с React компонентами потребуется настроить Babel вместе с Rollup для транспиляции JSX:
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
Также нужно создать .babelrc или babel.config.json файл с соответствующими пресетами:
{ "presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ] }
Это позволяет Babel корректно обрабатывать файлы .tsx и .ts, содержащие JSX.
Больше практических инструментов эксперты из OTUS рассматривают в рамках онлайн-курсов. С полным каталогом курсов можно ознакомиться по ссылке, а также не забывайте о нашем календаре бесплатных мероприятий.
ссылка на оригинал статьи https://habr.com/ru/articles/804133/
Добавить комментарий