Create a JavaScript library. Configure Dev Build using Rollup.js
Tags: javascript, webdev, rollup, sideprojects
Published: 2020-06-18 09:40:18

After writing an MVP for my third-party project (by the way, I have a separate [article about this](https://dev.to/alexandrshy/create-a-javascript-library-build-mvp-4i58)), I wrote a roadmap. One of the points was to create a dev build for convenient work of contributors. And I decided to do it immediately 🤘

## Current configuration

To build my tools I use [Rollup.js](https://rollupjs.org/). The config that we wrote earlier looks like this:

```js
import typescript from 'rollup-plugin-typescript2';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';

import pkg from './package.json';

const extensions = ['.js', '.jsx', '.ts', '.tsx'];

export default {
    input: 'src/index.ts',
    output: [
        {
            file: pkg.main,
            format: 'umd',
            name: 'Keukenhof',
        },
        {
            file: pkg.module,
            format: 'es',
            name: 'Keukenhof',
        },
    ],
    plugins: [
        typescript({
            rollupCommonJSResolveHack: true,
            clean: true,
        }),
        babel({
            exclude: 'node_modules/**',
            extensions,
        }),
        resolve(),
        commonjs(),
        terser(),
    ],
};
```

I remind you what plugins we use now:

* **rollup-plugin-terser** - plugin to minimize compiled source code
* **rollup-plugin-typescript2** - plugin for typescript with compiler errors
* **@rollup/plugin-babel** - plugin for seamless integration between Rollup and Babel
* **@rollup/plugin-commonjs** - plugin to convert CommonJS modules to ES6, so they can be included in a Rollup bundle
* **@rollup/plugin-node-resolve** - plugin which locates modules using

And I use a script to start the build:

```
"build:lib": "rollup -c",
```

`-c` flag is short for `--config`, the configuration file is at the root of the project.

## Updated configuration

We want to get a new build for *developer mode* with a local dev server with LiveReload support. And the Rollup community has plugins for this. 

```
yarn add rollup-plugin-serve rollup-plugin-livereload -D
```

Great, the plugins are installed, but we only need them for the build devs, and we'll use the current build in GitHub CI to prepare the library for publication. For this, I'll use two separate `Rollup` configuration files. 

I created a separate directory `config/rollup` and put two configuration files (`rollup.config.dev.js` and `rollup.config.lib.js`) so as not to store everything in the root of the project. `rollup.config.lib.js` is just the renamed current configuration file. And we'll make small changes to the `rollup.config.dev.js` package:

```js
import typescript from 'rollup-plugin-typescript2';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';

import pkg from '../../package.json';

const extensions = ['.js', '.jsx', '.ts', '.tsx'];

export default {
    input: 'src/index.ts',
    output: [
        {
            file: `./example/${pkg.main}`,
            format: 'umd',
            name: 'Keukenhof',
        },
        {
            file: `./example/${pkg.module}`,
            format: 'es',
            name: 'Keukenhof',
        },
    ],
    plugins: [
        typescript({
            rollupCommonJSResolveHack: true,
            clean: true,
        }),
        babel({
            exclude: 'node_modules/**',
            extensions,
        }),
        resolve(),
        commonjs(),
        serve({
            open: true,
            openPage: '/',
            host: 'localhost',
            port: 3003,
            contentBase: ['./example'],
        }),
        livereload({
            watch: ['./example'],
            exts: ['html', 'js', 'css'],
        }),
    ],
};
```

For plugins and output, we defined a new directory, `example`, in this directory will contain page layout, styles, and library build. Any change to the files with the extension `html`, `js`, `css` will lead to reload the page. The dev server will be available at the following URLs `http://localhost:3003/` and will open automatically after the build.

The layout has the following structure:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./style.css" />
    <script src="./dist/index.js"></script>
  </head>
  <body>
    ...
  </body>
  <script src="./script.js"></script>
</html>
```

Now we need to update the scripts to start the build

```json
"build:lib": "rollup --config config/rollup/rollup.config.lib.js",
"build:dev": "rollup --config config/rollup/rollup.config.dev.js -w",
```

This is very similar to what it was before, only we explicitly specified the paths to configs, since we now have two configs and in the config for build devs we specified the `-w ' flag, this flag is needed in order to monitor files and rebuild on changes.

If everything was done correctly, the `build:dev` script should lead to the project being built in the `example` directory. Also, make sure that changing the styles or layout will automatically reload the page. This helps reduce development time

If you are creating libraries that other people can use, you need to take care of the documentation. Documentation should be as simple and clear as possible, so that the person who is just starting to use your project does not experience difficulties.

Dev build is needed for people who will want to participate in the development process, so I have indicated step by step how it works in `README.md` file.

By the way, I also shot the whole process on the video, you can see it is very short

{% youtube uUJl0u2wWAE %}

## Links

* [Rollup.js documentation](https://rollupjs.org/guide/en/)
* [rollup-plugin-serve](https://github.com/thgh/rollup-plugin-serve)
* [rollup-plugin-livereload](https://github.com/thgh/rollup-plugin-livereload)

___

[Keukenhof](https://github.com/Alexandrshy/keukenhof/blob/v1.1.2/rollup.config.js) is the library I'm working on, at the moment it is under active development, but maybe you want to subscribe and follow this step by step