Rollup React Library
Intro
Rollup is a module bundler to compile the Javascript code. In the previous post explained rollup basics.
In this post let's see how we can build and publish react library using rollup and npm.
Requirements
We have the following requirements.
- React
- Typescript
- SASS
- Eslint
- Storybook support
- Yarn/Npm
- Semantic Versioning
The Component Library
Create a new folder rollup-react-libarary
. Initilize npm with yarn init
and git init
➜ yarn init
yarn init v1.22.4
question name (rollup-react-library):
question version (1.0.0):
question description: rollup react library
question entry point (index.js): dist/index.umd.js
question repository url: http://github.com/dimpu/rollup-react-library.git
question author (dimpu):
question license (MIT):
question private: false
success Saved package.json
✨ Done in 72.06s.
Since we are creating react library we need to add react
, react-dom
as peer dependency.
yarn add react react-dom -P
yarn add @types/react typescript -D
Now you should see following in your package.json
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
}
Eslint
Add eslint
npx eslint --init
Answer few questions
npx: installed 107 in 4.737s
? How would you like to use ESLint? …
To check syntax only
To check syntax and find problems
❯ To check syntax, find problems, and enforce code style
✔ How would you like to use ESLint? · style
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
CommonJS (require/exports)
None of these
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
? Which framework does your project use? …
❯ React
Vue.js
None of these
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
? Which framework does your project use? …
❯ React
Vue.js
None of these
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
✔ Node
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
✔ Node
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
? How would you like to define a style for your project? …
❯ Use a popular style guide
Answer questions about your style
Inspect your JavaScript file(s)
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
? How would you like to define a style for your project? …
❯ Use a popular style guide
Answer questions about your style
Inspect your JavaScript file(s)
This will add all required packages.
Then add lint
command to scripts.
scripts: {
....
lint: eslint src/**/*.{tsx,ts}
lint-fix: eslint src/**/*.{tsx,ts} -- --fix
....
}
Storybook
To setup storybook run
npx -p @storybook/cli sb init
This will setup storybook and adds storybook packages and command to package.json
scripts.
By default storybooks only support Javascript. We need to support Typescript and sass so let's add it.
yarn add ts-loader @storybook/addon-info react-docgen-typescript-loader style-loader css-loader sass-loader -D
Then update .storybook/main.js
module.exports = {
stories: ["../src/**/*.stories.tsx"],
addons: ["@storybook/addon-actions", "@storybook/addon-links"],
webpackFinal: async (config) => {
config.module.rules.push(
{
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve("ts-loader"),
},
{
loader: require.resolve("react-docgen-typescript-loader"),
},
],
},
{
test: /\.s[ac]ss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
}
);
config.resolve.extensions.push(".ts", ".tsx");
return config;
},
};
Run yarn storybook
to run the storybook.
Source Code
Let's create src
folder.
Let's add Gavatar
component to the source.
Gavatar.tsx
import React, { useEffect, useState } from 'react';
import md5 from 'md5';
import styles from './Gavatar.scss';
interface Props {
email: string;
size?: number;
}
export default ({ email, size = 300 }: Props) => {
const [emailMd5, setEmailMd5] = useState('//www.gravatar.com/avatar/');
useEffect(() => {
setEmailMd5(`//www.gravatar.com/avatar/${md5(email)}?s=${size}`);
}, [email]);
return (
<div className={styles.box}>
<img alt="" src={emailMd5} />
</div>
);
};
Gavatar.scss
.box {
border: 1px solid #ccc;
width: 300px;
height: 300px;
img {
padding: 5px;
background: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
width: 100%;
height: 100%;
border: 1px solid #ddd;
}
}
Gavatar.stories.ts
import React from 'react';
import Gavatar from './Gavatar';
export default {
title: 'Gavatar',
component: Gavatar,
};
export const GavatarStory = () => <Gavatar email="<your email" />;
That's now if you already running Storybook using yarn storbook
you should see
Rollup
Let add rollup to the repo.
yarn add rollup @rollup/plugin-typescript rollup-plugin-scss @rollup/plugin-commonjs -D
Add rollu.config.js
import typescript from '@rollup/plugin-typescript';
import scss from 'rollup-plugin-scss';
import commonjs from '@rollup/plugin-commonjs';
import pkg from './package.json';
export default {
input: 'src/index.tsx',
output: [
{
file: pkg.main,
format: 'umd',
},
{
file: pkg.module,
format: 'esm',
},
],
plugins: [
commonjs(),
scss({
output: true,
}),
typescript(),
],
};
Update package.json
{
.....
"main": "dist/rollup-react-library.umd.js",
"module": "dist/rollup-react-library.esm.js",
....
"scripts": {
....
"build": "rollup -c"
}
}
That's it now if you run yarn build
you should see a dist
folder generated with *.umd.js
& *.ems.js
.
Yarn Publish
To distrubute your package as node module. Just run yarn publish