How to Setup a TypeScript project using Rollup.js

thisdotmedia_staff

This Dot Media

Posted on December 29, 2020

How to Setup a TypeScript project using Rollup.js

A couple of months ago, I started to work through web standards, Rollup.js, and TypeScript. It’s my first experience using Rollup although I’ve been working with TypeScript on different projects and using it along other frameworks like Angular.

So far, it has been a good experience in terms of performance and tools integration.

rollup-typescript

What is Rollup?

In words of the official documentation:

Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application...

What does that mean? Let’s start by saying that JavaScript improved drastically since ES6, and now it’s possible to define small portions of code that can be shared using two magical keywords: import and export. This specification is supported by modern browsers and tools. Rollup allows writing a future-proof code using the new module system without missing the compatibility with other module systems like CommonJS, AMD, and others.

Rollup also is considered as the "Next-generation ES module bundler", an alternative to the very known bundler Webpack.

Project Setup

Let's start building a small application based in TypeScript. Our first goal would be to compile and build it using Rollup.

Prerequisites

You need to install the following tools in your local environment:

  • Node.js. Preferably the latest LTS version.
  • A package manager. You can use either NPM or Yarn. This tutorial will use NPM.

Initialize the Project

You'll need a new folder to get started, you can create it from a command-line interface or from your favorite IDE/Code Editor:

mkdir typescript-rollup
cd typescript-rollup
Enter fullscreen mode Exit fullscreen mode

Let's start running the first command inside that folder to create the package.json file and have an initialized project. This will be useful to manage and install packages later.

npm init -y
Enter fullscreen mode Exit fullscreen mode

The previous command will create the package.json with some defaults. You can edit that file later according to your needs:

{
  "name": "typescript-rollup",
  "version": "1.0.0",
  "description": "A basic TypeScript project built using Rollup.js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/luixaviles/typescript-rollup.git"
  },
  "keywords": [],
  "author": "Luis Aviles <@luixaviles>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/luixaviles/typescript-rollup/issues"
  },
  "homepage": "https://github.com/luixaviles/typescript-rollup#readme"
}
Enter fullscreen mode Exit fullscreen mode

Use npm init only if you want to set your preferences with the interactive mode of the command.

Source Code Files

Let's create a library to perform basic Math operations and perform strings processing. The project will contain the following source files:

|- typescript-rollup
    |- src/
        |- math/
            |- math.ts
            |- index.ts
        |- string/
            |- string.ts
            |- index.ts
        |- app.ts
Enter fullscreen mode Exit fullscreen mode

Add the Math operations in math/math.ts file:

export function add(x: number, y: number): number {
  return x + y;
}

export function substract(x: number, y: number): number {
  return x - y;
}
Enter fullscreen mode Exit fullscreen mode

Then, the strings operations will be defined in string/string.ts file:

export const toLowerCase = (input: string): string => {
  return input.toLocaleLowerCase();
};

export const toUpperCase = (input: string): string => {
  return input.toUpperCase();
};
Enter fullscreen mode Exit fullscreen mode

In the latest file, we're exporting a function using the ES6 Arrow function expression.

In order to import related functions regardless of the filenames, we can create the index.ts files in both directories:

// src/math/index.ts
export { add, substract } from './math';

// src/string/index.ts
export { toLowerCase, toUpperCase } from './string';
Enter fullscreen mode Exit fullscreen mode

Pay attention to the src/app.ts file:

import { add, substract } from './math';

const x = 20;
const y = 10;

console.log(`${x} + ${y} = ${add(x, y)}`)
console.log(`${x} - ${y} = ${substract(x, y)}`);
Enter fullscreen mode Exit fullscreen mode

The app.ts file is the starting point of our application. Also, take a look at the first import line. We don't need to import those functions from ./math/math.ts file, since all of them have been exported in /math/index.ts file. Again, this is a convenient way to organize the library content using TypeScript.

Installing Rollup and TypeScript

Let's continue installing Rollup and TypeScript as development dependencies:

npm install --save-dev rollup typescript
Enter fullscreen mode Exit fullscreen mode

Additional tools are needed:

  • @open-wc/building-rollup, as a rollup plugin for integration between Rollup.js and TypeScript,
  • rimraf, which is the UNIX command rm -rf for Node.js
  • deepmerge, a tool to merge enumerable properties or more objects deeply.

Use a single command to have all of them as new dependencies:

npm install --save-dev @open-wc/building-rollup rimraf deepmerge
Enter fullscreen mode Exit fullscreen mode

TypeScript Configuration

For every TypeScript project, it's required to create the tsconfig.json file. It indicates that the directory is the root of a TypeScript project.

tsc --init
message TS6071: Successfully created a tsconfig.json file.
Enter fullscreen mode Exit fullscreen mode

Let's apply some changes to that file:

{
  "compilerOptions": {
    "target": "es2018",                          
    "module": "esnext",
    "moduleResolution": "node",                     
    "noEmitOnError": true,
    "lib": ["es2017"],                            
    "strict": true,  
    "esModuleInterop": false,                 
    "outDir": "out-tsc",
    "rootDir": "./"
  }
  ,
  "include": ["./src/**/*.ts"]
}
Enter fullscreen mode Exit fullscreen mode

The most important thing here is the outDir option since the value says where the JavaScript files will be generated. Also, the include parameter will list a set of patterns of the files to be included in the compilation.

Learn more about the compilerOptions and the tsconfig.json file in TsConfig Reference documentation.

Rollup Configuration

It's time to configure the module bundler tool: Rollup. You can use Rollup from a command-line interface along with parameters. However, you can provide a configuration file to simplify the usage and provide advanced functionality.

Let's create a rollup.config.js file with the next content:

// rollup.config.js

import merge from 'deepmerge';
import { createBasicConfig } from '@open-wc/building-rollup';

const baseConfig = createBasicConfig();

export default merge(baseConfig, {
  input: './out-tsc/src/app.js',
  output: {
      dir: 'dist',
  }
});
Enter fullscreen mode Exit fullscreen mode

Take a look at the documentation if you're curious about the different ways to use these configuration files. Also, find an example of the TypeScript support provided by @open-wc/building-rollup package.

The Build script

In the package.json file, define a script to compile the input files and run the previous configurations:

{
  ...
  "scripts": {
    "build": "rimraf dist && tsc && rollup -c rollup.config.js"
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

Here's what is happening with the script:

  • rimraf dist, will make sure to clean up the output directory for Rollup: dist
  • tsc, will run the TypeScript compiler through the configurations defined in tsconfig.json file. The output content will be located in the ./out-tsc directory, as defined in the TypeScript configuration file.
  • rollup -c rollup.config.json, will run Rollup and take the ./out-tsc directory as input and put the result in a dist folder. Those configurations are defined in the rollup.config.js file.

Generate the Build and Run the App

Run the build script using:

npm run build
Enter fullscreen mode Exit fullscreen mode

You'll have the following output:

npm run build

> typescript-rollup@1.0.0 build /Users/luixaviles/projects/github/typescript-rollup
> rimraf dist && tsc && rollup -c rollup.config.js

./out-tsc/src/app.js → dist...
created dist in 300ms
Enter fullscreen mode Exit fullscreen mode

Finally, run the single file generated as a result of the build script:

node dist/7b857f5b.js 
20 + 10 = 30
20 - 10 = 10
Enter fullscreen mode Exit fullscreen mode

You'll see the expected output.

The Final Project Structure

You should have the following project structure, including the source code files and configurations:

|- typescript-rollup
    |- src/
        |- math/
            |- math.ts
            |- index.ts
        |- string/
            |- string.ts
            |- index.ts
        |- app.ts
    |- package.json
    |- rollup.config.js
    |- tsconfig.json
Enter fullscreen mode Exit fullscreen mode

Alternatives to integrate Rollup and TypeScript

In case you're planning to build a SPA project(Single Page Application), you can use the createSpaConfig in Rollup configuration. Also, you can install the @rollup/plugin-typescript for seamless integration between Rollup and TypeScript.

// rollup.config.js
import merge from 'deepmerge';
import { createSpaConfig } from '@open-wc/building-rollup';
import typescript from '@rollup/plugin-typescript';

const baseConfig = createSpaConfig();

export default merge(baseConfig, {
  input: './index.html',
  plugins: [typescript()],
});
Enter fullscreen mode Exit fullscreen mode

The @rollup/plugin-typescript will load any compilerOptions from the tsconfig.json file by default. However, there's an option to override those configurations:

// rollup.config.js

...
export default merge(baseConfig, {
  input: './index.html',
  plugins: [typescript({target: "es5"})],
});
Enter fullscreen mode Exit fullscreen mode

In case you prefer a simple configuration, then you can set the rollup.config.js file using only this plugin:

// rollup.config.js
import typescript from '@rollup/plugin-typescript';

export default {
  input: 'src/app.ts',
  output: {
    dir: 'output',
    format: 'cjs',
  },
  plugins: [typescript()],
};
Enter fullscreen mode Exit fullscreen mode

Or even better, use the open-wc project generator for an automated setup through Rollup, TypeScript, and even Web Components.

Source Code of the Project

Find the complete project in this GitHub repository: typescript-rollup. Do not forget to give it a star ⭐️ and play around with the code.

You can follow me on Twitter and GitHub to see more about my work.

This Dot Labs is a modern web consultancy focused on helping companies realize their digital transformation efforts. For expert architectural guidance, training, or consulting in React, Angular, Vue, Web Components, GraphQL, Node, Bazel, or Polymer, visit thisdotlabs.com.

This Dot Media is focused on creating an inclusive and educational web for all. We keep you up to date with advancements in the modern web through events, podcasts, and free content. To learn, visit thisdot.co.

💖 💪 🙅 🚩
thisdotmedia_staff
This Dot Media

Posted on December 29, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related