ES6 Modules: Rollup

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 // размер файла в байтах для инлайнинга изображений
    }),
  ],
};

Now you can add an image to the folder src and use it in CSS or JavaScript. For example, in styles.css:

body {
  background-image: url('./background.png');
  background-size: cover;
}

Or directly to index.js:

import background from './background.png';

document.body.style.backgroundImage = `url('${background}')`;

We will also install some necessary plugins

@rollup/plugin-node-resolve: allows Rollup to connect external modules from node_modules:

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

Let's include in the configuration file:

import resolve from '@rollup/plugin-node-resolve';
export default {
  //...
  plugins: [resolve()]
};

You can install it in exactly the same way:

@rollup/plugin-commonjs: converts CommonJS modules to ES6 format that Rollup can handle.

@rollup/plugin-json: Allows Rollup to import data from JSON files.

@rollup/plugin-babel: integrates Babel to transpilate code to older versions of JavaScript.

For Babel you will need to create.babelrc with Babel settings:

{
  "presets": [
    ["@babel/preset-env", {
      "modules": false
    }]
  ]
}

@rollup/plugin-terser: minifies the final bundle for production.

Main features of Rollup

Tree Shaking

Tree Shaking is the process of eliminating code that is not actually used in the project.

Tree-Shaking works by analyzing the code files needed to run an application and only including the code that is actually used by the application. This process creates a data structure representing the intent of your code, consisting of nodes that represent the code (functions, statements, etc.). These nodes form a tree-like structure, and once created, you can determine what code is actually being used by the application.

Tree-Shaking in JS works by using ES6 modules because they are static in their structure. Each file analyzed by the Tree-Shaking process will have different kinds of export statements as the top-level node of the data structure being created. In the files that these exported members import, import usage can be tracked.

Let's look at an example of using Tree-Shaking using Rollup, demonstrating how unused code can be excluded from the final bundle.

Let's assume there are two module files: math.js And main.js. IN math.js several functions are defined, but main.js only uses one of them.

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

If we use Rollup to build, it analyzes the dependencies and understands that only the function sum used in main.js. Functions multiply And subtract are not used and therefore may be excluded from the final bundle thanks to the Tree-Shaking mechanism.

To run Tree-Shaking with Rollup, you can use the following Rollup configuration file rollup.config.js:

export default {
  input: 'main.js', // точка входа вашего приложения
  output: {
    file: 'bundle.js', // имя итогового файла
    format: 'es' // формат модулей в итоговом бандле
  }
};

Then we run Rollup with this configuration and it will generate bundle.js, containing only the code used. As a result, the resulting file size will be smaller and the application will load faster.

Code Splitting

Code-Splitting allows you to split code into different parts based on different entry points and dynamic imports, using an output format import mechanism instead of custom loader code. This allows parts of the application to be loaded dynamically as needed.

To demonstrate Code Splitting using Rollup, let's look at an example where we have two entry points into an application and dynamically import a module.

Project structure:

  • src/

    • main1.js (entry point 1)

    • main2.js (entry point 2)

    • shared.js (module used by both entry points)

    • dynamic.js (module imported dynamically)

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

To support Code Splitting in a Rollup configuration, you need to define both entry points and configure the output parameters to generate multiple chunks:

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 is defined as an array with two entry points. Rollup will analyze dependencies, detect common modules and dynamic imports, and split the code into chunks accordingly. As a result, shared.js will be placed in a separate chunk, since it is used by both entry points, while dynamic.js will be loaded dynamically only when needed.

Setting up Rollup to work with TypeScript, React

To get started with TypeScript and React, you need to install the appropriate packages and dependencies:

npm i --save-dev typescript react react-dom @types/react

To integrate TypeScript into a project with Rollup, use the plugin @rollup/plugin-typescript. The simplest configuration file rollup.config.js might look like this:

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

export default {
  input: 'src/index.tsx', // точка входа приложения
  output: {
    dir: 'dist', // каталог для сгенерированных файлов
    format: 'esm', // формат модуля ES
  },
  plugins: [typescript()],
};

This configuration tells Rollup to process TypeScript files and assemble them into ES6 modules.

File tsconfig.json contains TypeScript compiler settings. Basic configuration example:

{
  "compilerOptions": {
    "outDir": "./dist",
    "module": "ESNext",
    "target": "es5",
    "jsx": "react",
    "declaration": true,
    "declarationDir": "./dist"
  },
  "include": ["src/**/*"]
}

There will be support for JSX, generation of type declarations and compilation in ES5 for better compatibility.

To work with React components, you will need to configure Babel along with Rollup for JSX transpilation:

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

You also need to create .babelrc or babel.config.json file with the corresponding presets:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

This allows Babel to process files correctly .tsx And .tscontaining JSX.


Experts from OTUS discuss more practical tools in online courses. With a complete catalog of courses you can check out the linkand also don’t forget about our calendar free events.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *