Creating and Publishing a React Component Library as a NPM Package via React, Storybook adn Rollup
Initiating Base Setup - any one from the two below
I. With NPM INIT
Star with an empty folder and creates a package.json
npm init
Create directories:
my-react-lib └── src ├── components └── index.js
add dependencies only in development mode
npm install --save-dev react react-dom
Add a peerDependencies object in package.json and add the dev dependencies:
"peerDependencies": { "react": "^17.0.2", "react-dom": "^17.0.2" }
II. With create-react-app
- Personal Suggestion, as i struggled with above method
Star with an empty folder and initialise create-react-app
npx create-react-app my-react-lib
Add a peerDependencies object in package.json and add the dev dependencies:
"peerDependencies": { "react": "^17.0.2", "react-dom": "^17.0.2" }
Installing StoryBook for Designing Components - (optional)
Install StoryBook
npx sb init
Note: Preparing to install dependencies. ✓ in terminal after installation indicates:\ Dev-dependencies are already detected.
Create new directory in components:
my-react-lib └── src ├── components │ └──Reqirements └── index.js
Create:
my-react-lib ├── src ├── components │ └──Reqirements │ ├──Requirements.jsx │ └── index.js └── index.js
Remember :
the file src/index.js in src must have all components that need to be consumed as a package in the user's app
After Creating a demo component(Requirements.jsx in our case); \ run storybook, just to check things are working, before which, \ make a story in stories directory:
make a storybook stork, just to see whether the component is working or not
Installing Dependencies
Installing rollup and other packages in devDependencies:
$ npm install rollup rollup-plugin-babel @rollup/plugin-node-resolve rollup-plugin-peer-deps-external @babel/preset-react rollup-plugin-postcss rollup-plugin-terser --save-dev
Function of each dependency:
@rollup/plugin-node-resolve
resolve third party dependencies, and add it to source code
rollup
to bundle the application
rollup-plugin-babel
allows to integrate with existing babel config
rollup-plugin-peer-deps-external
excludes any peerDependencies from our bundle, meaning exclude 'react' and 'react-dom' from our bundled source code.
@babel/preset-react
to handel JSX and other react goodies
rollup-plugin-postcss
to bundle all the css files
rollup-plugin-terser
to minify jsvascript
Configuring Rollup
Making a Rollup Script to bundle the application, \ by creating a rollup.config.js file in root directory
my-react-lib ├── src ├── package-lock.js ├── package.js └── rollup.config.js
Configure the rollup.config.js file
import babel from 'rollup-plugin-babel'; import resolve from '@rollup/plugin-node-resolve'; import external from 'rollup-plugin-peer-deps-external'; import { terser } from 'rollup-plugin-terser'; import postcss from 'rollup-plugin-postcss'; // config for rollup export default [ { // application entry point input: './src/index.js', // exporting our package output: [ { file: 'dist/index.js', format: 'cjs', }, { file: 'dist/index.es.js', format: 'es', exports: 'named', } ], plugins: [ postcss({ plugins: [], minimize: true, }), babel({ exclude: 'node_modules/**', presets: ['@babel/preset-react'] }), external(), resolve(), terser(), ] } ];
Changing package.json
In package.json file, add the below Rollup script to bundle the app
"build-lib": "rollup -c"
also add these two lines in package.json, before publishing it to
{ "main": "dist/index.js", "module": "dist/index.es.js", }
Final version of
package.json
:{ "name": "mm-demo-pkg", "version": "0.1.0", "description": "A React component library to Design React apps painlessly", "author": "Apurv Chimralwar", "main": "dist/index.js", "module": "dist/index.es.js", "license": "MIT", "dependencies": {}, "peerDependencies": { "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.2.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "build-lib": "rollup -c" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@babel/core": "^7.14.0", "@babel/preset-react": "^7.13.13", "@rollup/plugin-node-resolve": "^11.2.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.2.0", "rollup": "^2.46.0", "rollup-plugin-babel": "^4.4.0", "rollup-plugin-peer-deps-external": "^2.2.4", "rollup-plugin-postcss": "^4.0.0", "rollup-plugin-terser": "^7.0.2" } }
Note before publishing it to npm
Before publishing it to npm via github repo make sure you are just pushing *dist, package.json and the readme.md*
Publishing to NPM
Create an Npm Account
Run the following command in terminal, and fill the npm account details
$ npm login
At last run npm publish, to publish to npm
$ npm publish