Create Reusable React Components with TS and Rollup
Rushil dhinoja
Posted on March 22, 2022
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
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
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 😊
Posted on March 22, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.