Creating a reusable React component library as an NPM package with Storybook for documentation is a great way to share components across projects or with other developers. Here’s a step-by-step guide to creating, testing, and publishing a React component library.
1. Set Up the Project Structure
- Create a New Directory and Initialize the Project
mkdir my-react-library
cd my-react-library
npm init -y
- Install Necessary Dependencies
Install React, Babel for transpiling, Storybook for documentation, and other necessary tools.
npm install react react-dom
npm install --save-dev @babel/cli @babel/preset-env @babel/preset-react babel-loader
npm install --save-dev storybook @storybook/react webpack webpack-cli
- Add Babel Configuration
Create a.babelrcfile to configure Babel to use React and modern JavaScript syntax:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
- Create Basic Folder Structure
Inside your project folder, create the following structure:
my-react-library
├── src
│ └── components
│ └── Button.js
├── .babelrc
├── package.json
└── README.md
2. Create a Component
Create a simple reusable Button component in src/components/Button.js:
// src/components/Button.js
import React from 'react';
import PropTypes from 'prop-types';
const Button = ({ label, onClick, style }) => {
return (
<button onClick={onClick} style={style}>
{label}
</button>
);
};
Button.propTypes = {
label: PropTypes.string.isRequired,
onClick: PropTypes.func,
style: PropTypes.object,
};
Button.defaultProps = {
onClick: () => {},
style: {},
};
export default Button;
3. Configure Storybook
- Initialize Storybook
Initialize Storybook in the project:
npx storybook init
This will create a .storybook directory and add necessary dependencies.
- Add a Story for the Button Component
Create a new file,Button.stories.js, in the same directory as theButtoncomponent:
// src/components/Button.stories.js
import React from 'react';
import Button from './Button';
export default {
title: 'Components/Button',
component: Button,
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
label: 'Click Me',
style: { backgroundColor: 'blue', color: 'white' },
};
export const Secondary = Template.bind({});
Secondary.args = {
label: 'Secondary',
style: { backgroundColor: 'gray', color: 'black' },
};
- Run Storybook
Add a script inpackage.jsonto run Storybook:
"scripts": {
"storybook": "start-storybook -p 6006"
}
Now you can start Storybook with:
npm run storybook
This should open Storybook in your browser with your Button component.
4. Configure Webpack for Library Publishing
Create a webpack.config.js file for building the component library:
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/components/Button.js', // entry point of the library
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
library: 'myReactLibrary',
libraryTarget: 'umd',
umdNamedDefine: true,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
],
},
externals: {
react: 'react',
'react-dom': 'react-dom',
},
};
5. Build the Library
Add a build script in package.json:
"scripts": {
"build": "webpack --config webpack.config.js"
}
Run the build command:
npm run build
After this, you should see a dist folder with your index.js file, which is your compiled library.
6. Prepare for Publishing
- Add Files to .npmignore
To avoid publishing unnecessary files, create a.npmignorefile:
node_modules
src
.storybook
.babelrc
webpack.config.js
- Update
package.jsonwith Main and Module Fields
Setmainto point to your built file:
"main": "dist/index.js",
7. Publish to NPM
- Log in to NPM
npm login
- Publish the Package
npm publish
Once published, you can install your package in other projects by running:
npm install my-react-library
8. Using the Library
In another project, you can use the library like this:
import React from 'react';
import Button from 'my-react-library';
const App = () => (
<div>
<Button label="My Reusable Button" />
</div>
);
export default App;
Summary
With this setup, you now have a reusable React component library, complete with Storybook documentation and published to NPM for easy reuse and distribution. This structure also allows you to add more components, update existing ones, and document them in Storybook as your library evolves.
