Using StorybookJS in a component library package with React as peer dependency

Viewed 2178

I am creating my own React component library. The package.json is using react and react-dom as peer dependencies because I only want to ship code for components only. This package will then be used in other React-based projects so I will provide React myself in those projects.

I've decided for adding StorybookJS in the package for two reasons

  1. Help during development to preview my components
  2. Create a static storybook site that I will host somewhere showcasing the components

My project structure:

package.json
src/
  components/ // contains components
  storybook/ // <-- not part of the package
  index.ts  // <-- this is entry point of the package

However this introduces a problem. Since StorybookJS requires react and react-dom to run, I would have to include them as dependencies of the library.

I will be using webpack to actually bundle only the component code so it can be distributed. Should I just use externals property in configuration to exclude react and react-dom from the bundle? I guess it would work but then the package.json would still list React as its dependencies (which I do not want).

What is the correct approach here?

1 Answers

I ended up putting react and react-dom into peerDependencies as that is correct approach in my opinion. Since that package file belongs to library itself (and not Storybook), it should correctly state its dependencies.

To avoid bundling React into my library bundle, I put it into externals webpack configuration like so:

  externals: {
    react: 'react',
    'react-dom': 'react-dom',
  },

This way, React or ReactDOM does not end up in the bundle. The library is React component library so it can't be used without React anyway and you should provide it.

The final step to make Storybook work, I added prepare script that installs peer dependencies when you install the package. That way React and ReactDOM are provided for Storybook application.

This is the prepare script in my package.json:

"scripts": {
  "prepare": "install-peers && npm run build"
}

I used install-peers package to install React and ReactDOM. For newer version of NPM client, you will not need this package and running npm install should install peer dependencies as well.

Related