Create a React component library with Vite and Typescript

Most of the time, we use our favorite tool to create a React application: create react app, next, gatsby…
But, it’s a different story when it comes to building a component library. The choice is not straightforward. This article will show how to crea…


This content originally appeared on DEV Community and was authored by Nicolas Erny

Most of the time, we use our favorite tool to create a React application: create react app, next, gatsby...
But, it's a different story when it comes to building a component library. The choice is not straightforward. This article will show how to create a library with Vite and Typescript.

Why Vite?

Vite is a modern frontend tooling with excellent performance. You can get more details here. Out of the box, it supports typescript and library bundles. Therefore, it's a perfect choice to create a React library.

How to structure and organize our project?

Let's start creating a monorepo. We use yarn workspaces to manage dependencies.
To configure our monorepo, we need to create a package.json file at the repository's root.

{
  "name": "lib-example",
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*",
      "sites/*"
    ]
  },  
}

The repository has two folders:

  • packages containing the component library package
  • sites containing the site to test the library

Here's the tree structure.

react-library-vite-example
|- packages
|  |- my-lib
|- sites
|  |- my-site
|- package.json
|- yarn.lock

Library package

Inside the packages folder, let's create a new Vite project:

yarn create vite my-lib --template react-ts

By default, it creates a React web app configured with typescript. Now, we have to customize it to use the library mode from Vite.

First, we have to install a vite plugin to help us generate the type definitions for our components.

yarn add --dev vite-plugin-dts

To bundle the library, we need to update the vite.config.js file.

import react from '@vitejs/plugin-react';
import path from 'node:path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';

export default defineConfig({
    plugins: [
        react(),
        dts({
            insertTypesEntry: true,
        }),
    ],
    build: {
        lib: {
            entry: path.resolve(__dirname, 'src/lib/index.ts'),
            name: 'MyLib',
            formats: ['es', 'umd'],
            fileName: (format) => `my-lib.${format}.js`,
        },
        rollupOptions: {
            external: ['react', 'react-dom', 'styled-components'],
            output: {
                globals: {
                    react: 'React',
                    'react-dom': 'ReactDOM',
                    'styled-components': 'styled',
                },
            },
        },
    },
});

Notice that it's also important to externalize any dependencies you do not want to bundle into your library: react, react-dom, and styled-components.
Our rollup configuration generates two bundle formats: es and umd.

We add the following button component (MyButton.tsx) to our library as an example.

import styled from 'styled-components';

const MyButton = styled.button`
    border: none;
    border-radius: 0.5rem;
    background-color: #186faf;
    color: hsl(0deg, 0%, 98%);
    padding: 0.75rem;
    cursor: pointer;
    &:hover {
        background-color: #0a558c;
    }
    &:focus {
        outline: none;
        box-shadow: 0 0 0 2px #62b0e8;
        background-color: #0a558c;
    }
`;

export default MyButton;

All the public React components are exported in the file src/lib/index.ts.

export { default as MyButton } from './MyButton';

Here's the updated package.json for our library:

{
    "name": "my-lib",
    "version": "0.0.0",
    "scripts": {
        "dev": "vite",
        "build": "tsc && vite build",
        "preview": "vite preview"       
    },
    "dependencies": {
        "react": "^17.0.2",
        "react-dom": "^17.0.2",
        "styled-components": "^5.3.3"
    },
    "devDependencies": {
        "@babel/core": "^7.16.12",
        "@types/node": "^17.0.12",
        "@types/react": "^17.0.38",
        "@types/react-dom": "^17.0.11",
        "@types/styled-components": "^5.1.21",
        "@vitejs/plugin-react": "^1.1.4",
        "acorn-jsx": "^5.3.2",
        "babel-loader": "^8.2.3",
        "typescript": "^4.5.5",
        "vite": "^2.7.13",
        "vite-plugin-dts": "^0.9.9"
    },
    "license": "UNLICENSED",
    "peerDependencies": {
        "react": "^16.8.0 || 17.x",
        "react-dom": "^16.8.0 || 17.x",
        "styled-components": "^5.0.0"
    },
    "files": [
        "dist"
    ],
    "main": "./dist/my-lib.umd.js",
    "module": "./dist/my-lib.es.js",
    "types": "./dist/index.d.ts",
    "exports": {
        ".": {
            "import": "./dist/my-lib.es.js",
            "require": "./dist/my-lib.umd.js"
        }
    }
}

Run yarn build to compile the library.

As we bundle the dependencies into the library (except for the externals), we have to clean up the package.json of the published npm package. We do this by adding a prepack script.

"prepack": "json -f package.json -I -e \"delete this.devDependencies; delete this.dependencies\"",

I use a CLI for working with JSON (yarn add -D json).

Website to test the component library

Let's start by creating a new Vite project in the sites folder.

yarn create vite my-site --template react-ts

We need to add the following dependency to our package.json file to test our component library:

"dependencies": {
   "my-lib": "*",
   ...
},

Now, we can reference and use our button component.

import { MyButton } from 'my-lib';

function App() {    
    return (
        <div className="App">
            ...
                    <MyButton onClick={...}>Click here!</MyButton>
            ...                
        </div>
    );
}

export default App;

Run yarn install and yarn run dev to start the dev server.

Configure storybook

We also want to create documentation for our UI components. Storybook is a fantastic project to help us create a playground for our React components.

Run the following command to configure Storybook:

cd /packages/my-lib && npx sb init --builder storybook-builder-vite

At the time of writing, the interactions addon does not work well with Vite. Here's the customized configuration (.storybook/main.js):

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
  ],
  framework: "@storybook/react",
  core: {
    builder: "storybook-builder-vite",
  },
};

Finally, we create a story file for our button component.

import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import MyButton from './MyButton';

const meta: ComponentMeta<typeof MyButton> = {
    title: 'Design System/MyButton',
    component: MyButton,
};
export default meta;

export const Primary: ComponentStoryObj<typeof MyButton> = {
    args: {
        disabled: false,
        children: 'Hello',
    },
};

Run yarn run storybook to start the storybook.

Library storybook

If you want to learn more about Storybook, check out the official documentation.

What's next?

We've just created an excellent Vite startup project. But, we can go further and configure additional tools such as eslint, prettier, jest...

You can find the source code on Github.
This has been helpful for me in my projects. Hopefully it helps you as well.


This content originally appeared on DEV Community and was authored by Nicolas Erny


Print Share Comment Cite Upload Translate Updates
APA

Nicolas Erny | Sciencx (2022-04-11T16:55:13+00:00) Create a React component library with Vite and Typescript. Retrieved from https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/

MLA
" » Create a React component library with Vite and Typescript." Nicolas Erny | Sciencx - Monday April 11, 2022, https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/
HARVARD
Nicolas Erny | Sciencx Monday April 11, 2022 » Create a React component library with Vite and Typescript., viewed ,<https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/>
VANCOUVER
Nicolas Erny | Sciencx - » Create a React component library with Vite and Typescript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/
CHICAGO
" » Create a React component library with Vite and Typescript." Nicolas Erny | Sciencx - Accessed . https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/
IEEE
" » Create a React component library with Vite and Typescript." Nicolas Erny | Sciencx [Online]. Available: https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/. [Accessed: ]
rf:citation
» Create a React component library with Vite and Typescript | Nicolas Erny | Sciencx | https://www.scien.cx/2022/04/11/create-a-react-component-library-with-vite-and-typescript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.