Creating and Publishing a React Component Library as a NPM Package via React, Storybook adn Rollup

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

  1. Star with an empty folder and creates a package.json

    npm init
    
  2. Create directories:

    my-react-lib
      └── src
           ├── components
           └── index.js
    
  3. add dependencies only in development mode

    npm install --save-dev react react-dom
    
  4. 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

  1. Star with an empty folder and initialise create-react-app

    npx create-react-app my-react-lib
    
  2. 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)

  1. Install StoryBook

    npx sb init
    

Note: Preparing to install dependencies. ✓ in terminal after installation indicates:\ Dev-dependencies are already detected.

  1. Create new directory in components:

    my-react-lib
      └── src
           ├── components
           │     └──Reqirements
           └── index.js
    
  2. Create:

    my-react-lib
            ├── src
            ├── components
            │     └──Reqirements
            │              ├──Requirements.jsx
            │              └── index.js
            └── index.js
    
  3. 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
    
  4. 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

  1. 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
    
  2. Function of each dependency:

    1. @rollup/plugin-node-resolve

      resolve third party dependencies, and add it to source code
      
    2. rollup

      to bundle the application
      
    3. rollup-plugin-babel

      allows to integrate with existing babel config
      
    4. rollup-plugin-peer-deps-external

      excludes any peerDependencies from our bundle, meaning exclude 'react' and 'react-dom' from our bundled source code.
      
    5. @babel/preset-react

      to handel JSX and other react goodies
      
    6. rollup-plugin-postcss

      to bundle all the css files
      
    7. rollup-plugin-terser

      to minify jsvascript
      

Configuring Rollup

  1. 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
    
  2. 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

  1. In package.json file, add the below Rollup script to bundle the app

    "build-lib": "rollup -c"
    
  2. also add these two lines in package.json, before publishing it to

    {
        "main": "dist/index.js",
        "module": "dist/index.es.js",
    }
    
  3. 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

  1. Create an Npm Account

  2. Run the following command in terminal, and fill the npm account details

    $ npm login
    
  3. At last run npm publish, to publish to npm

    $ npm publish