Search code examples
reactjsnpmstorybook

How to package .scss files when publishing Storybook components in npm package?


I just published my Storybook components in an npm package (let's call it my-storybook) and followed this tutorial: https://storybook.js.org/tutorials/design-systems-for-developers/react/en/distribute/

but when I tried to use them in a project, I get the following error for each component exported in my package:

Compiled with problems:

ERROR in ./node_modules/my-storybook/dist/stories/Button/Button.js 14:0-24

Module not found: Error: Can't resolve './button.scss' in '/Users/storybook-test/my-app/node_modules/my-storybook/dist/stories/Button'

My Storybook component folder structure is like this:

/src
 /stories
   /Button
     Button.jsx
     button.scss
     Button.stories.jsx

As per the tutorial linked above, the build script for the publish is this:

"build": "cross-env BABEL_ENV=production babel src -d dist"

In my index.js, I export the components like so:

export * from "./stories/Button/Button";

When I went into the dist folder I saw that the .scss files were not being included with the export. I'm not sure if it's supposed to include them, but I don't know how to resolve this error. The dist folder tree looks like this:

/dist
 /stories
   /Button
     Button.js
     Button.stories.js

Both files in the dist folder have the line require("./button.scss"); and that is the line that is giving me the error.

How can I resolve the error above when I try to import my components in a new React app? Any ideas would be appreciated. Thank you kindly.

EDIT: Here is my .storybook/main.js file

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    "@storybook/preset-create-react-app",
  ],
  framework: "@storybook/react",
  core: {
    builder: "@storybook/builder-webpack5",
  },
  staticDirs: ["../public"],
};

Solution

  • I had exactly the same problem and I managed to solve it using rollup.js instead of webpack. Took me a little bit of time to get my head around it but it solved a lot of problems.

    I like it because it transpiles the code (including scss) into single file cjs which makes it easier when importing.

    This is the documentation I used and this video was also helpful:

    This is my package.json file:

    {
      "name": "seb-storybook-test",
      "version": "1.0.13",
      "description": "just playing around",
      "main": "dist/index.js",
      "module": "dist/index.es.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "storybook": "start-storybook -p 6006",
        "build-storybook": "build-storybook",
        "build-lib": "rollup -c --bundleConfigAsCjs"
      },
      "files": [
        "dist"
      ],
      "author": "Sebastian Meckovski",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.19.3",
        "@rollup/plugin-node-resolve": "^15.0.0",
        "@storybook/addon-actions": "^6.5.12",
        "@storybook/addon-essentials": "^6.5.12",
        "@storybook/addon-interactions": "^6.5.12",
        "@storybook/addon-links": "^6.5.12",
        "@storybook/builder-webpack4": "^6.5.12",
        "@storybook/manager-webpack4": "^6.5.12",
        "@storybook/react": "^6.5.12",
        "@storybook/testing-library": "^0.0.13",
        "babel-loader": "^8.2.5",
        "postcss": "^8.4.17",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "rollup": "^3.1.0",
        "rollup-plugin-babel": "^4.4.0",
        "rollup-plugin-peer-deps-external": "^2.2.4",
        "rollup-plugin-postcss": "^4.0.2",
        "rollup-plugin-scss": "^3.0.0",
        "rollup-plugin-terser": "^7.0.2",
        "sass": "^1.55.0",
        "sass-loader": "^13.1.0",
        "storybook-addon-sass-postcss": "^0.1.3"
      },
      "peerDependencies": {
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
      }
    }
    

    and this is the rollup.config.js:

    import babel from "rollup-plugin-babel";
    import resolve from "@rollup/plugin-node-resolve";
    import external from "rollup-plugin-peer-deps-external";
    import scss from "rollup-plugin-scss";
    import { terser } from "rollup-plugin-terser";
    
    export default [
      {
        input: "./src/index",
        output: [
          {
            file: "dist/index.js",
            format: "cjs",
          },
        ],
        plugins: [
          scss({
            insert: true,
          }),
          babel({
            exclude: "node_modules/**",
            presets: ["@babel/preset-react"],
          }),
          external(),
          resolve(),
          terser(),
        ],
      },
    ];
    

    Hope this helps.

    Edit 1:

    Attaching my GitHub repo so you can check detailed setup