Create Reusable React Components with TS and Rollup
Tags: react, typescript, javascript, component
Published: 2022-03-22 15:23:52

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
```
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"
  }
}
```
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"],
};
```

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"]
}
```

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;
```

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";
```

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

```
yarn install
yarn build
```

If everything is done properly you may get this message

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojtckcjeidjbm4wj7glo.png)

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
```

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

```
yarn link react-lib
```

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;
```

The end result will look something like this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtnx25p8rbzjub12bwep.png)

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](https://github.com/Molecule-UI/moleculeui) 

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