banhmi123
banhmi123

Reputation: 15

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"],
};

Upvotes: 1

Views: 990

Answers (1)

Sebastian Meckovski
Sebastian Meckovski

Reputation: 278

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

Upvotes: 2

Related Questions