Storybook: CSS modules

Created on 22 Jun 2016  路  20Comments  路  Source: storybookjs/storybook

Hi, I'm trying to use SASS styles like this in my React components:

import React, { Component } from 'react';
import Drawer from 'material-ui/Drawer';
import { Link } from 'react-router' ;
import styles from './sidebar.scss' ;

class Sidebar extends Component {
  constructor(props) {
    super(props);
    this.state = { open: true };
  }

  render() {
    return (
      <div>
        <Drawer className={styles.drawer} open={this.state.open}>
          <div className={styles.header}>
            <Link className={styles.profilePic} to="#">Item</Link>
          </div>
          <Link className={styles.item} to="#">Profile</Link>
          <Link className={styles.item} to="#">Dashboard</Link>
          <Link className={styles.item} to="#">Charts</Link>
          <Link className={styles.item} to="#">Calendar</Link>
        </Drawer>
      </div>
    );
  }
}

export default Sidebar;

Styles are working in my app normally, all good. But when I open them in storybook, styles won't show up. Is this problem with my webpack setup for storybook? Here is how it looks like:

const path = require('path');
const autoprefixer = require('autoprefixer');

module.exports = {
  module: {
    loaders: [
      {
        loader: 'url-loader?limit=10000',
        test: /\.(gif|jpg|png|svg)$/,
        include: path.resolve(__dirname, '../')
      }, {
        loader: 'url-loader?limit=1',
        test: /favicon\.ico$/,
        include: path.resolve(__dirname, '../')
      }, {
        loader: 'url-loader?limit=100000',
        test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
        include: path.resolve(__dirname, '../')
      },
      {
        loader: 'style-loader!css-loader',
        test: /\.css$/,
        include: path.resolve(__dirname, '../'),
        exclude: path.resolve(__dirname, '../node_modules')
      },
      {
        loader: 'style-loader!css-loader!sass-loader',
        test: /\.scss$/,
        include: path.resolve(__dirname, '../'),
        exclude: path.resolve(__dirname, '../node_modules')
      },
    ]
  },
  sassLoader: {
    includePaths: path.resolve(__dirname, '../src/browser')
  },
};

If I import styles with import './sidebar.scss' ; and then write class names explicitly into classNames, then styles are used correctly in storybook (so SASS files are loaded without problem, loaders in webpack works).

What should I do if I want to use styles like I shown in my Sidebar component on top of this comment?

Most helpful comment

For webpack 2 I'm using this in .storybook/webpack.config.js and it's working fine:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
        ],
      },
    ],
  },
}

All 20 comments

We're having this problem too, but with PostCSS. Any help here is appreciated.

Is it possible to send me a sample repo, I can work with this.
So, I can find out the problem with PostCSS o SASS.

seems like when I use this loader setup in my app's webpack config:

      {
        test: /\.css?$/,
        loaders: [ 'style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' ],
        include: path.resolve(__dirname, '../')
      },
      {
        test: /\.scss$/,
        loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
        include: path.resolve(__dirname, '../')
      }

and the same in storybooks webpack:

     {
        test: /\.css?$/,
        loaders: [ 'style', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' ],
        include: __dirname
      },
      {
        test: /\.scss$/,
        loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
        include: __dirname
      }

Then CSS modules works from both plain .css files and also from .scss files.
Installed packages sass-loader, css-loader. Example repo:
https://github.com/michaltakac/react-storybook-demo/tree/sass-css-modules, branch sass-css-modules.

Or check commit: https://github.com/michaltakac/react-storybook-demo/commit/aa13f1db42f457765e8177cd5a943945083c2106

Maybe I guess this can be closed then? @nickick @arunoda

Thansk @michaltakac for the sample.
I'll close this issue.

This solution seems to not work anymore. I'm having trouble getting CSS modules (specifically, React CSS Modules) to work within Storybook.

Steps:

  1. create-react-app
  2. Get Storybooks setup
  3. Load component that uses React CSS Modules

+1

I am having the same issue here. I can't make it work with css modules.

@arunoda

I got it to work, thanks. Just for future reference, if you want to just add css modules to your react storybook project:

  1. add a webpack.config.js on your .storybook directory

  2. put this inside:

module.exports = {
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: 'style!css?modules'
      }
    ]
  }
}
  1. be happy with sane css in storybook :)

Guys (particularly @arunoda), do you have any clue what I could be doing wrong here? Styles from CSS Modules don't show up in the storybook despite the solution you've provided above. I've officially run out of ideas.

const path = require('path');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: 'style!css?modules'
      },
      {
        test: /\.scss$/,
        loader: 'style!css!sass',
        exclude: /node_modules/,
        include: path.resolve(__dirname, '../../')
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loaders: [
          'file?hash=sha512&digest=hex&name=[hash].[ext]',
          'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      },
    ]
  },
}

Not working at all

Since webpack released version 2.0, I think it might have affected how css modules settings work.

For webpack 2 I'm using this in .storybook/webpack.config.js and it's working fine:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
        ],
      },
    ],
  },
}

@MacroWorms It works like a charm. Thank you for updating the solution.

@MarcoWorms works as of Nov 10th, thanks for sharing!

The upcoming version of https://github.com/facebook/create-react-app (v2) will have support for css-modules. How could storybook detect that?

@MarcoWorms works for me as of Aug. 2nd. Thanks!

the above is invalid as of Feb. 2019.
Just found storybooks has a dependency on react-scripts.
just install react-scripts and everything should work...
Happy coding!

I had similar issues and this config ended up working for me.

module.exports = (BaseConfig, env, defaultConfig) => {
  const rules = [];
  // Do this because sass-loader does not like it when there are
  // multiple declarations of it in rules.. and we want css modules
  // turned on
  defaultConfig.module.rules.forEach(rule => {
    const testCssString = "myscss.scss";
    const regex = RegExp(rule.test);
    if(!regex.test(testCssString)){
      rules.push(rule);
    }
  });
  defaultConfig.module.rules = rules;

  defaultConfig.module.rules = [
    {
      test: /\.scss$/,
      include: srcDir,
      loaders: [
        "style-loader",
        {
          loader: "css-loader",
          options: {
            importLoaders: "1",
            localIdentName: "[name]__[local]___[hash:base64:5]",
            modules: true,
          }
        },
        "sass-loader"
      ]
  },
      {
        test: /\.svg$/,
        issuer: {
          test: /.jsx?$/
        },
        use: ['@svgr/webpack']
      },
  ...rules
  ]

the above is invalid as of Feb. 2019.
Just found storybooks has a dependency on react-scripts.
just install react-scripts and everything should work...
Happy coding!

Thanks @madhudskumar! Installing react-scripts worked for me in a Gatsby project

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tlrobinson picture tlrobinson  路  3Comments

sakulstra picture sakulstra  路  3Comments

levithomason picture levithomason  路  3Comments

tirli picture tirli  路  3Comments

arunoda picture arunoda  路  3Comments