View on GitHub

Tech, Games and Whisky

The Sebr's Blog

Rollup

|

I developed my ui library SPUI (shameless plug) using Typescript. And I wanted a way to easily distribute the library and make it available both for javascript development environment as well as typescript.

By default, typescript will transpile all your .ts in .js. But then you have to do something to properly include them in a webapp. Do you use a module loading system like requirejs or SystemJs? Or do you use a bundler like webpack or browserify?

I have already admitted in this post that I hate to configure development environment or toolchain. I like to code not to edit configuration file!

Turns out there is a simple alternative: RollupJs. This is a bundler that is super easy to configure, that outputs easy to read javascript (I am looking at you webpack) in a single library file and that does “tree-shaking” which is a hipster way to saying it will only bundles code that is actually used. For example, if you want to bundle your sweet webapp that only uses 2 functions from library XYZ, it will only include those 2 functions in the resulting bundled file and not all the functions of the library.

Rollup also uses javascript as its format for configuration file! Not YML (I am looking at you travis) or any other json based config format. Plain Old Javascript. This means your configuration file can include code!

SPUI (another plug) rollup.config.js looks like this:

import sourceMaps from 'rollup-plugin-sourcemaps';

const path = require('path');
const fs = require('fs');

const inputBasePath = 'es';
const outputBasePath = 'dist';

function createBundleConfig(input, outputName = undefined, bundleName = undefined) {
    const inputFile = path.join(inputBasePath, input);
    const outFile = path.join(outputBasePath, outputName || input);
    return {
        input: inputFile,
        output: {
            file: outFile,
            format: "umd"
        },
        sourcemap: true,
        name: bundleName,
        plugins: [
            sourceMaps()
        ]
    }
}

const examples = fs.readdirSync('examples').map(exampleDir => {
    const example = path.join('examples', exampleDir, 'index.ts');
    if (fs.existsSync(example)) {
        return example.replace('.ts', '.js');
    }
}).filter(exampleFile => !!exampleFile);

const exampleConfigs = examples.map(input => createBundleConfig(input));

export default [
    createBundleConfig('spui/index.js', 'spui.js', 'spui'),
    createBundleConfig('tests/spec.js'),
    ...exampleConfigs
]

I basically use nodejs fs to look at all the examples and bundle each of them in their own app.

To produce a bundle for SPUI I only need to execute 2 commands:

tsc && rollup -c rollup.config.ts

Which translates to use tsc to transpile all javascript to a folder than use rollup to bundle the whole library. As you see in the rollup.config.js file we indicate to rollup what is the “main” file of the library: index.js. And then rollup will walk through the import and export statements and find everything that is needed to bundle spui.js in a single file. Voila!

Rollup supports a slew of other features: plugins, lots of module formats support, sourcemaps and such. For SPUI (third time is the charm) the barest minimum was all it took and that is mighty fine with me!

As a side node the Typescript Library Starter boilerplate that I alluded to in a previous post is already setup for rollup!