LTFoReal
LTFoReal

Reputation: 457

issue loading css module classes in storybook v6.4

I'm having trouble getting storybook to play nice with css modules within my Gatsby project. I'm able to render the button component but it does not add any of my styling. On inspection of the element, I'm only getting undefined undefined from the following code.

button.jsx

import React from "react"
import * as css from "./style.module.css"

const Button = ({ variant = "button", type, value = null }) => {
  const baseOfVariant = () => {
    if (variant === "input") {
      return (
        <input
          type={type}
          value={value}
          className={`${css.button} ${css.clear_button}`}
        />
      )
    }
    return (
      <button type={type} className={`${css.button} ${css.submit_button}`}>
        {value}
      </button>
    )
  }
  return baseOfVariant()
}

export default Button

button.stories.jsx

import React from "react"
import Button from "./button"

export default {
  title: "Button",
  component: Button,
}

export const Template = args => <Button {...args} />

export const ButtonRegular = Template.bind({})
ButtonRegular.args = {
  variant: "button",
  value: "Click Me",
  type: "submit",
}

main.js

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  core: {
    builder: "webpack5",
  },
}

Storybook stuff in my devDeps

"devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/polyfill": "^7.12.1",
    "@storybook/addon-actions": "^6.4.0-alpha.2",
    "@storybook/addon-essentials": "^6.4.0-alpha.2",
    "@storybook/addon-links": "^6.4.0-alpha.2",
    "@storybook/addon-viewport": "^6.4.0-alpha.2",
    "@storybook/builder-webpack5": "^6.4.0-alpha.2",
    "@storybook/manager-webpack5": "^6.4.0-alpha.2",
    "@storybook/react": "^6.4.0-alpha.2",
    "babel-loader": "^8.2.2",
    "prettier": "2.2.1",
    "resize-observer-polyfill": "^1.5.1"
  }

Upvotes: 2

Views: 3175

Answers (2)

m-farhan
m-farhan

Reputation: 1426

If any one is looking for sass/scss related fix

import * as style from "./style.module.scss"

Where Storybook recognizes only this synthax:

your .storybook/main.js file.

 const path = require("path");
    
    module.exports = {
        stories: ["../src/**/*.stories.{js,mdx}"],
        addons: [
            "@storybook/addon-docs",
            "@storybook/addon-actions",
            "@storybook/addon-controls",
            "@storybook/addon-a11y",
            "@storybook/addon-viewport",
        ],
        // https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324
        core: {
            builder: "webpack5",
        },
        webpackFinal: async config => {
            // https://www.gatsbyjs.com/docs/how-to/testing/visual-testing-with-storybook/
            config.module.rules.push({
                test: /\.(js)$/,
                use: [
                    {
                        loader: require.resolve("babel-loader"),
                        options: {
                            presets: [
                                // use @babel/preset-react for JSX and env (instead of staged presets)
                                require.resolve("@babel/preset-react"),
                                require.resolve("@babel/preset-env"),
                            ],
                            plugins: [
                                // use @babel/plugin-proposal-class-properties for class arrow functions
                                require.resolve("@babel/plugin-proposal-class-properties"),
                                // use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
                                require.resolve("babel-plugin-remove-graphql-queries"),
                                // use babel-plugin-react-docgen to ensure PropTables still appear
                                require.resolve("babel-plugin-react-docgen"),
                            ],
                        },
                    },
                ],
                exclude: [/node_modules\/(?!(gatsby)\/)/],
            });
    
            config.module.rules.push({
                test: /\.s[ac]ss$/i,
                oneOf: [
                    // module.scss files (e.g component styles.module.scss)
                    // https://webpack.js.org/loaders/style-loader/#modules
                    {
                        test: /\.module\.s?css$/,
                        use: [
                            // Add exports of a module as style to DOM
                            {
                                loader: "style-loader",
                                options: {
                                    esModule: true,
                                    modules: {
                                        namedExport: true,
                                    },
                                },
                            },
                            // Loads CSS file with resolved imports and returns CSS code
                            {
                                loader: "css-loader",
                                options: {
                                    esModule: true,
                                    modules: {
                                        namedExport: true,
                                    },
                                },
                            },
                            // Loads and compiles a SASS/SCSS file
                            {
                                loader: "sass-loader",
// only if you are using additional global variable
                                options: {
                                    additionalData: "@import 'src/styles/global.scss';",
                                    sassOptions: {
                                        includePaths: ["src/styles"],
                                    },
                                },
                            },
                        ],
                    },
                    // scss files that are not modules (e.g. custom.scss)
                    {
                        use: [
                            // Add exports of a module as style to DOM
                            "style-loader",
                            // Loads CSS file with resolved imports and returns CSS code
                            "css-loader",
                            // Loads and compiles a SASS/SCSS file
                            {
                                loader: "sass-loader",
// only if you are using additional global variable
                                options: {
                                    additionalData: "@import 'src/styles/global.scss';",
                                    sassOptions: {
                                        includePaths: ["src/styles"],
                                    },
                                },
                            },
                        ],
                    },
                ],
            });
    
            return config;
        },
    };

With the above configuration, Storybook now accept this import synthax and button.jsx is correctly styled.

import * as styles from "./style.module.scss"

Upvotes: 0

Jerboas86
Jerboas86

Reputation: 664

Gatsby needs to import css modules with the following synthax:

import * as css from "./style.module.css"

Where Storybook recognizes only this synthax:

import css from "./style.module.css"

This is due to the fact that Gatsby and Storybook don't use the same import convention. Fortunately, you can configure Storybook css module import mechanism via .storybook/main.js file.

const path = require("path")

module.exports = {
  // You will want to change this to wherever your Stories will live
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  core: {
    builder: "webpack5",
  },
  webpackFinal: async config => {
    // Prevent webpack from using Storybook CSS rules to process CSS modules
    config.module.rules.find(
      rule => rule.test.toString() === "/\\.css$/"
    ).exclude = /\.module\.css$/

    // Tell webpack what to do with CSS modules
    config.module.rules.push({
      test: /\.module\.css$/,
      include: path.resolve(__dirname, "../src"),
      use: [
        {
          loader: "style-loader",
          options: {
            modules: {
              namedExport: true,
            },
          },
        },
        {
          loader: "css-loader",
          options: {
            importLoaders: 1,
            modules: {
              namedExport: true,
            },
          },
        },
      ],
    })
    // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
    config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]
    // use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
    config.module.rules[0].use[0].options.plugins.push(
      require.resolve("babel-plugin-remove-graphql-queries")
    )
    return config
  },
}

With the above configuration, Storybook now accept this import synthax and button.jsx is correctly styled.

import * as css from "./style.module.css"

Upvotes: 2

Related Questions