How to Set Up Rollup for a React Application?
Tags: webdev, javascript, tutorial, frontend
Published: 2023-03-17 16:06:07

## Introduction

React is one of the most popular libraries out there to create interactive UIs in today's fast-paced and modern technological world. One of the core features of React that makes it intuitive enough to work with is JSX. JSX is simply a syntax extension to JavaScript, which has to be processed by some kind of a tool before the code could be sent to a browser for execution.

This preprocessing of JSX is the job of transpilers, the most common one being Babel. However, almost no one uses Babel as a standalone tool — more often than not, it's used together with a bundler.

*Now what on Earth is a bundler?*

Well, from the perspective of a web application, a bundler tool is simply a means of taking all the multiple JavaScript files involved in building the application and then bundling them together into one single JavaScript file to be served to the client.

This, as you can reason, improves the network latency of the app, and also improves the loading times of the app. In this article, we'll see how to install and set up **Rollup**, a bundler tool, to help us build React applications.

-----

## What is Rollup?

You might've heard of [Webpack](https://webpack.js.org/) as a bundler from discussions on the setup of React. **Rollup** is a lightweight alternative to Webpack.

> 
At its core, Rollup is a bundler software that helps us bundle JavaScript modules together.

Its distinctive feature is that it's designed to work with ECMAScript modules.

The official website of Rollup, [rollupjs.org](https://rollupjs.org/) is a really nice source of information for bundling in general and for Rollup's setup.

![rollupjs.org - Rollup's official site.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arep2a66mntvwez2mj3q.png)

Rollup may be lighter in weight and complexity than Webpack, but by no means is it an elementary bundler. No. Rollup is definitely a complex module bundler software that comes equipped with numerous bells and whistles for different kinds of bundling concerns.

*It's surely worth a try.*

-----

## The React application

Before we dive into exploring how to get Rollup set up to bundle a React application, let's first define some starting code that'll eventually get bundled in the following sections.

Go ahead and create a `project1` directory anywhere on your operating system where you find it convenient to access, usually which is just the Desktop.

Then create the following set of files in it:


![Project structure for a React app.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r76ae7q6a7zkk67n4o78.png)

If you've worked with React before, you'll surely know that this file setup is simply meant to neatly structure our React application.

All the source files go in the `src` directory while the public-facing files go in the `public` directory.

The `node_modules` directory is created automatically by Node, while the `package.json` file (and `package-lock.json`) is necessary to describe the project and all of its package dependencies.

*Quite basic.*

Here's the code of the `index.js` file:

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './App';

ReactDOM.createRoot(document.querySelector('#root')).render(
   <App/>
);
```

It simply loads another file's exported `App` component and renders it inside a `#root` DOM element.

Here's the code of `App.js`:

```javascript
import React from 'react';

function App() {
   return (
      <h1>Rollup is amazing!</h1>
   );
}

export default App;
```

And here's the code of `index.html`:

```html
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Project 1</title>
</head>
<body>
   <div id="root"></div>
   <script src="bundle.js"></script>
</body>
</html>
```

Take note of the `<script>` tag at the end of `<body>` here. It refers to a file called `bundle.js` in the `public` directory, which as of yet doesn't exist.

Our bundling process will end up with a `bundle.js` file in `public` which'll eventually allow us to run the React application.

Here's the content of the `package.json` file:

```json
{
  "name": "project1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-react": "^7.18.6",
  }
}
```

As is apparent by this file, we are assuming that we have the following packages already installed in our setup: `react` and `react-dom` for React, and `@babel/core` and `@babel/preset-react` to be able to convert JSX in normal JavaScript code.

With this setup understood, let's now move over to installing Rollup.

-----

## Installing Rollup and its plugins

Installing Rollup is superbly simple.

Navigate to the `project1` directory that you created above and run the following command:

```
.../project1> npm install rollup --save-dev
```

This installs the `rollup` package as a developer dependency (because of the `--save-dev` flag).

We install `rollup` as `--save-dev` since it isn't used while running the application — rather it's only used when building the app and, likewise, it's only required by a developer working with the application's code.

Anyways, moving on, with `rollup` installed, now we have to install four Rollup plugins that'll help us bundle our React applications.

These plugins are described as follows:

### `@rollup/plugin-node-resolve`

When we have an absolute import in a module file such as `import 'react'`, we technically want the underlying bundler to know how to extract the desired package from the `node_modules` directory. This is known as [Node's module resolution algorithm](https://nodejs.org/api/modules.html#all-together).

Rollup, by default, doesn't know of or use this algorithm to resolve absolute imports.

In order to get it to do so, we need the **`node-resolve`** plugin which tells Rollup how to find packages/modules in the `node_modules` directory.

### `@rollup/plugin-commonjs`

By design, Rollup is meant to work with ECMAScript modules, i.e. the ones with `import` and `export` keywords. It's not designed to be paired with CommonJS modules, like the `react` package.

To be able to process CommonJS modules using Rollup, we ought to tell it that it needs to parse a CommonJS module. And this is done via the **`commonjs`** plugin.

### `@rollup/plugin-babel`

As we stated at the start of this article, React uses JSX which ought to be processed before it could be run. The de facto JSX preprocessor in use across the globe is Babel.

To use Babel along with Rollup, we need the **`babel`** plugin which automatically loads Babel and runs it based upon a `.babelrc.json` file at the project's root or based upon configurations sent into the plugin right at the time of its invocation (which we'll see shortly below).

### `@rollup/plugin-replace`

There is a special processing that needs to be done in order to be able to work with React packages. That is, the `react` package has a statement in it that refers to a property `env` on a global variable called `process`.

If you're experienced with Node.js, you'll realize that this statement won't work in the browser as it accesses the `process` variable which is only available in Node.js. In order to get our React program to run without any errors in the browser, we need to replace this statement with a dummy value. That's what the **`replace`** plugin is used for.

With the purpose of each of these plugins clear, let's go on and install all four of them.

Here's the command to run:

```
.../project1> npm install @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-babel @rollup/plugin-replace --save-dev
```

As with the `rollup` package, don't forget to include the `--save-dev` flag while installing these plugins, as they're all tied to Rollup which itself is a dev dependency.

With all the plugins installed, we are now left with configuring Rollup. And that means to create a **`rollup.config.mjs`** file at the project's root.

-----

## Configuring Rollup

Go ahead and create a `rollup.config.mjs` file at the root of the project's directory.

Rollup uses this configuration file before it performs the bundling process. The structure of the file is really simple. The default export of the file, which is merely a pure object, specifies all of the settings that we want to have in our bundling routine.

Here is a description of some of the most common properties of this exported object:

- **`input`** specifies the path of the input file.
- **`output`** specifies an object containing two properties: `file` that tells about the destination file path and `format` that provides the format of the output file. Possible values for format are 'iife', 'umd', 'cjs', etc.
- The **`plugins`** property is a list of all plugins to use in our Rollup setup.

Let's now get our `rollup.config.mjs` set up:

```javascript
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import replace from '@rollup/plugin-replace';

export default {
   input: 'src/index.js',
   output: {
      file: 'public/bundle.js',
      format: 'iife'
   },
   plugins: [
      nodeResolve({
         extensions: ['.js']
      }),
      babel({
         babelHelpers: 'bundled',
         presets: ['@babel/preset-react'],
         extensions: ['.js']
      }),
      commonjs(),
      replace({
         preventAssignment: false,
         'process.env.NODE_ENV': '"development"'
      })
   ]
}
```

Here's what's happening here:

Firstly, since the input file is `index.js` in the `src` directory, the value of input becomes `'src/index.js'`.

Secondly, since we want the bundled file to be called `bundle.js` in the `public` directory, the value of the `file` property of `output` becomes `'public/bundle.js'`. The `format` is chosen as `'iife'` because it's pretty basic of a setting.

Moving on, next we have a sequence of all the plugins to load in order to correctly bundle the React application.

With this configuration file set up, go on and add a **`build`** script in the `package.json` file to be able to quickly and conveniently run the `rollup` command for the bundling:


```json
{
   "name": "project1",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
      "build": "rollup -c -w",
      "test": "echo \"Error: no test specified\" && exit 1"
   },
   ...
}
```

In the command `rollup -c -w`, the `-c` flag tells Rollup that there is a configuration file it should use to understand the desired bundling process, while the `-w` flag instructs it to watch all the files involved in the bundling and then automatically rerun the bundling process as soon as any one of them changes.

Now, let's run this `build` command and let the magic happen:

```
.../project1> npm run build
```

Once the bundling is complete, we could open up the `index.html` file in the browser to see the app running. But before we do that, let's install the **`serve`** package so that the `public` directory is served on a localhost server.

Technically, React could be used without spinning up a localhost server, but it's a recommendation, the absense of which raises a warning in the console, and so we'll do it. It's really simple, thanks to the `serve` package.

Run the following command to install `serve`:

```
.../project1> npm install serve
```

Next up, define the **`start`** script in `package.json` to the string `'serve ./public'`, in order to run the `serve` command, serving up the `public` directory:

```json
{
   "name": "project1",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
      "build": "rollup -c -w",
      "start": "serve ./public",
      "test": "echo \"Error: no test specified\" && exit 1"
   },
   ...
}
```

Now when we execute the `npm start` command, the `serve` package would fire up, serving the `public` directory over localhost.

Let's get that done:

```
.../project1> npm start
```

And now we could view our application in the browser by navigating to localhost:3000.

![React application running on localhost:3000.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/box1lbn4mij661ld17ho.png)

*Perfect.*

-----

## In the end

So this was it for setting up Rollup to be able to work with React applications. Rollup is, without any doubt whatsoever, an awesome tool to use as an alternative to Webpack, which can get really complex at times.

What's best about using Rollup is that it gets frequent updates and has an active developer community behind it and so we could expect some nice oven-freshness in this lightweight bundler tool.

If you want to ramp up your Rollup's setup, you could create a task in VSCode to call the `npm build` command via a quick keyboard shortcut. VSCode is really configurable and that's something we as developers must leverage.

Have a great time coding in React. 🙂

And don't forget to check out the list of some awesome [courses on programming at CodeGuage](https://www.codeguage.com/courses/), crafted comprehensively and absolutely free to learn from.