How to build component library with React Typescript & Rollup

Posted on March 30th, 2021

The main content is how to create an ui library with react typescript + rollup.

Features:

  • Storybook for UI development
  • Emotion for write CSS in JS
  • Jest Enzyme for testing
  • Babel for transpiling
  • Rollup for bundling

1. Main Directory Structure

  • src
    • lib
      • index.ts
      • Component1
        • index.tsx
        • Component1.stories.tsx
        • Component1.test.tsx
      • Component2
        • index.tsx
        • Component2.stories.tsx
        • Component3.test.tsx
      • ...
  • package.json
  • rollup.config.js
  • tsconfig-lib.json
  • tsconfig.json

2. Config Rollup build

npm init

Edit package.json:

{
  ...
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
      "dist"
  ],
  "scripts": {
      "build": "rm -rf dist && rollup -c",
      ...
  }
  ...
}
npm i @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-image @rollup/plugin-node-resolve rollup rollup-plugin-sass rollup-plugin-typescript2 -D

Create rollup.config.js in root project with below content:

import babel from "@rollup/plugin-babel";
import commonjs from "@rollup/plugin-commonjs";
import image from "@rollup/plugin-image";
import resolve from "@rollup/plugin-node-resolve";
import sass from "rollup-plugin-sass";
import typescript from "rollup-plugin-typescript2";
import pkg from "./package.json";

export default [
  {
    input: ["src/index.ts"],
    output: [
      {
        dir: "dist",
        format: "cjs",
        exports: "auto",
      },
    ],
    preserveModules: true,
    plugins: [
      typescript({ tsconfig: "tsconfig-lib.json" }),
      sass({
        insert: true,
      }),
      image(),
      babel({
        babelHelpers: "bundled",
        presets: ["@babel/preset-env", "@babel/preset-react"],
        extensions: [".js"],
        exclude: ["node_modules/**"],
      }),
      resolve(),
      commonjs(),
    ],
    external: [...Object.keys(pkg.peerDependencies || {})],
  },
];

For the full source code, please refer to the following this repo

3. How to use UI lib

Local import for development In UI project run

npm run build
yarn link

In Frontend project run

yarn link <ui-name>

Ex: yarn link @letrungdo/web-ui

4. Reduce size when importing

If use VS Code you should install Import Cost extension to view the size of the imported package:

import { Label } from "@letrungdo/web-ui/dist/lib/Label"; // 2.4K (gzipped: 1.1K)
import { Label } from "@letrungdo/web-ui"; // 3.9K (gzipped: 1.4K)

Above are two ways to import. => Should choose method 1 to reduce size.