Search code examples
reactjssassstorybook

Storybook: component level styles failing with sass-loader 12


I have Storybook setup in my project. The following is the main.js file:

const path = require('path');
const {
  webpack
} = require('../craco.config');

module.exports = {
  stories: ['../src/components/**/*.stories.@(js|jsx|ts|tsx)', '../src/components/**/*.stories.mdx'],
  addons: ['@storybook/addon-essentials'],
  framework: '@storybook/react',

  webpackFinal: async config => {
    config.resolve.alias = {
      ...config.resolve.alias,
      ...webpack.alias
    };

    config.module.rules.push({
      test: /.scss$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: true
          }
        },
        'sass-loader',
        {
          loader: 'sass-resources-loader',
          options: {
            resources: [path.resolve(__dirname, '../src/styles/_variables.scss')]
          }
        }
      ]
    });
    
    return config;
  },
  

  core: {
    builder: 'webpack5'
  }
};

This config enables the modules (so scss modules work as expected) but the regular scss does not work at all. The opposite happens if modules: true is not there but I cannot make it work both at the same time.

If I create two rules (one for .modules.scss and another for *.scss (not including modules):

const patterns = [
      '.module.scss',
      '(?!.*\.module\.scss$).*\.scss'
    ];
    
    patterns.forEach(pattern => {
      const rule = {
        test: new RegExp(`${pattern}$`),
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: pattern === '.module.scss',
            }
          },
          'sass-loader',
          {
            loader: 'sass-resources-loader',
            options: {
              resources: [path.resolve(__dirname, '../src/styles/_variables.scss')]
            }
          }
        ]
      };

      console.log(rule);
      config.module.rules.push(rule);
    });

I get the following error:

ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/button/style.module.scss 33:98  root stylesheet
    at processResult (/Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:758:19)
    at /Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:860:5
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:400:11
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:252:18
    at context.callback (/Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:5)
SassError: SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/button/style.module.scss 33:98  root stylesheet
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:14)
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/modal/style.module.scss 33:98  root stylesheet
    at processResult (/Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:758:19)
    at /Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:860:5
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:400:11
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:252:18
    at context.callback (/Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:5)
SassError: SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/modal/style.module.scss 33:98  root stylesheet
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:14)
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/text-area/style.module.scss 33:98  root stylesheet
    at processResult (/Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:758:19)
    at /Users/nkivatinetz/src/forseti/node_modules/webpack/lib/NormalModule.js:860:5
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:400:11
    at /Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:252:18
    at context.callback (/Users/nkivatinetz/src/forseti/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:5)
SassError: SassError: expected "{".
   ╷
33 │ var api = require("!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
   │                                                                                                  ^
   ╵
  src/components/text-area/style.module.scss 33:98  root stylesheet
    at Object.loader (/Users/nkivatinetz/src/forseti/node_modules/sass-loader/dist/index.js:69:14)

After doing some research I found that it may be a duplication of the loader but those files should be landing in only one rule.


Solution

  • Oh, I finally made it work. I had to add to the rules:

    {
       loader: 'css-loader',
       options: {
            modules: true, // Enable modules to help you using className
       }
    },