Create Reusable React Components with TS and Rollup

rushildhinoja

Rushil dhinoja

Posted on March 22, 2022

Create Reusable React Components with TS and Rollup

In today's time if you are a front-end dev you know that react is a synonym for resisability. The library designed to create a component based architecture.

If you are developer like me who has a bad habit of starting multiple side-projects at once then at least once in your life you must have thought of creating a collection of all your react components and reuse them in all your project.

If not, no worries today's the best time to give it a shot, this thought came to my mind in 2020 since then I have been working on creating a one-stop solution for all my future side project.

In this post I will share with you how can you setup a project to create a reusable components package which can be published to npm and be used as any other package.

Tech Stack

  • TypeScript
  • React
  • Rollup

First of we will setup up our project:
I would say to follow the exact same folder structure so that it will be easy to follow along

📦react-lib
 ┣ 📂build
 ┣ 📂src
 ┃ ┣ 📂components
 ┃ ┃ ┗ 📜Button.tsx
 ┃ ┗ 📜index.tsx
 ┣ 📜package.json
 ┣ 📜rollup.config.js
 ┣ 📜tsconfig.json
 ┗ 📜yarn.lock
Enter fullscreen mode Exit fullscreen mode

First of all there are some required things you need to add in package.json.

package.json

{
  "name": "react-lib",
  "version": "1.0.0",
  // Main will tell node to enter our library from this file (basically it will act as a entry point)
  "main": "build/index.js",
  "scripts": {
    "build": "rollup -c"
  },
  //These are dependencies we need only in the development process
  "devDependencies": {
    "@rollup/plugin-commonjs": "^21.0.2",
    "@types/react": "^17.0.41",
    "@types/react-dom": "^17.0.14",
    "rollup": "^2.70.1",
    "rollup-plugin-typescript2": "^0.31.2",
    "typescript": "^4.6.2"
  },
  //The files will define where our final bundle is located
  "files": [
    "build"
  ],
  "dependencies": {},
  //React and React DOM will peer dependencies because they will already be present in the project this package is being used.
  "peerDependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

In the beginning I used webpack to bundle my code but it was not easy to understand and maintain, later on I switched to gulp but gulp was not powerful enough and as they say third time's the charm I came around rollup it was powerful like webpack and was easy to configure like gulp

Rollup file is the most important file in this project, it will build our library

rollup.config.js

import typescript from "rollup-plugin-typescript2";

export default {
  //Will act as a entry point
  input: "./src/index.tsx",
  output: [
    {
      //Specify the output directory
      dir: "build",
      //We will be using commonjs as a format for bundling
      format: "cjs",
      exports: "named",
      //It will provide you the sourcemap for debugging
      sourcemap: true,
      strict: false,
    },
  ],
  //Preserve module will generate a transpiled file for every file in your src folder, if set false it will bundle all the code in one file
  preserveModules: true,
  //Rollup allows a rich set of plugins to be used along side, we are only using one to compile typescript code to JS
  plugins: [typescript({ tsconfig: "./tsconfig.json" })],
  //We will add React and React-dom as externals because our library will use these two packages from its parent
  external: ["react", "react-dom"],
};
Enter fullscreen mode Exit fullscreen mode

The next file is tsconfig.json I have kept it really simple but you can change as per your needs and standards

tsconfig.json

{
  "compilerOptions": {
    "module": "esnext",
    "declaration": true,
    "rootDir": "src",
    "outDir": "build",
    "target": "ES5",
    "moduleResolution": "Node",
    "jsx": "react",
    "noImplicitUseStrict": true,
    "allowSyntheticDefaultImports": true,
    "lib": ["es2015", "dom"]
  },
  "include": ["./src/*.tsx"],
  "exclude": ["node_modules", "build"]
}
Enter fullscreen mode Exit fullscreen mode

Now, let's write some components. For the purpose of this post I have created a simple Button Component which accepts two prop color and roundCorners.

We will create a src/components/button.tsx file and add the below code to it

src/components/button.tsx

import React from "react";

interface Props {
  color?: string;
  roundCorners?: boolean;
}

const Button: React.FC<Props> = (props) => {
  const { color, roundCorners } = props;

  return (
    <button
      style={{ background: color, borderRadius: roundCorners ? "6px" : "0" }}
    >
      Click me
    </button>
  );
};

Button.defaultProps = {
  color: "white",
  roundCorners: false,
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

Now we will import it to src/index.tsx and then we will be ready to create a build and use it in our projects

src/index.tsx

export { default as Button } from "./components/Button";
Enter fullscreen mode Exit fullscreen mode

Now, shoot up a terminal of your choice and run the following commands in order to create a build

yarn install
yarn build
Enter fullscreen mode Exit fullscreen mode

If everything is done properly you may get this message

Image description

Now, to use it in you local projects we can use yarn link command

First of all run the below command in your library project's root, it will create a symlink in you device

yarn link
Enter fullscreen mode Exit fullscreen mode

Now, to use it in any of your project you can use below command in your app directory's root

yarn link react-lib
Enter fullscreen mode Exit fullscreen mode

You will be able to use it as shown in below code

import { Button } from "react-lib";
function App() {
  return <Button roundCorners={true} />;
}

export default App;
Enter fullscreen mode Exit fullscreen mode

The end result will look something like this

Image description

If you are interested creating something more than just a button have a look at the project that gave me idea to write this post MoleculeUI

Follow for more such content in future.
Leave some feedback as it is my first post.
Thank You 😊

💖 💪 🙅 🚩
rushildhinoja
Rushil dhinoja

Posted on March 22, 2022

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

Sign up to receive the latest update from our blog.

Related