Модули ES6: Rollup

от автора

Привет, Хабр!

Когда-то были времена, когда весь 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *