Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling SCSS in Storybook with Gatsby

I have an existing GatsbyJS project and I want to add Storybook to this project to showcase each separate component. I'm using SCSS in my project, which are being compiled with gatsby-plugin-sass, which works great. However, I can't use my components in Storybook since it cannot compile the SCSS files.

I followed the instructions from both Storybook and GatsbyJS. This is how my storybook/webpack.config.js looks like:

module.exports = ({ config }) => {

  // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
  config.module.rules[0].exclude =
    [
      /node_modules\/(?!(gatsby)\/)/,
    ];

  // use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
  config.module.rules[0].use[0].loader = require.resolve('babel-loader');

  // use @babel/preset-react for JSX and env (instead of staged presets)
  config.module.rules[0].use[0].options.presets = [
    require.resolve('@babel/preset-react'),
    require.resolve('@babel/preset-env'),
  ];

  config.module.rules[0].use[0].options.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'),
  ];

  // Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
  config.resolve.mainFields = ['browser', 'module', 'main'];
  return config;
};

and my storybook/config.js file looks like this:

import { configure } from '@storybook/react';
import { action } from '@storybook/addon-actions';

// automatically import all files ending in *.stories.js
configure(require.context('../src', true, /\.stories\.js$/), module);

// Gatsby's Link overrides:
// Gatsby defines a global called ___loader to prevent its method calls from creating console errors you override it here
global.___loader = {
  enqueue: () => {
  },
  hovering: () => {
  },
};

// Gatsby internal mocking to prevent unnecessary errors in storybook testing environment
global.__PATH_PREFIX__ = '';

// This is to utilized to override the window.___navigate method Gatsby defines and uses to report what path a Link would be taking us to if it wasn't inside a storybook
window.___navigate = pathname => {
  action('NavigateTo:')(pathname);
};

I assume I need to add a sass-loader to the webpack config, however it does feel a bit unnatural to add another custom loader since GatsbyJS already handles my SCSS files.

I've been fiddling with adding sass-loader, css-loader and style-loader to my webpack.config.js, but I couldn't get it to work.

Also Googling this specific situation doesn't give me a lot of hits. I assume I'm not the first person who tries to do this.

like image 497
Martin van Houte Avatar asked Nov 08 '19 14:11

Martin van Houte


People also ask

How do I add SCSS to my Storybook?

In this case, you can either install and configure a Storybook preset (e.g., SCSS preset ), or customize Storybook's webpack configuration and include the appropriate loader. To use your CSS in all stories, you import it in .storybook/preview.js

How do I add Gatsby to my Storybook project?

You can streamline the entire configuration process by adding the storybook-addon-gatsby to your Gatsby project. Run the following command: Next, register the addon within Storybook’s main configuration file (i.e., .storybook/main.js ).

What is the difference between Sass and CSS in Gatsby?

In Gatsby, Sass code can be translated to well-formatted, standard CSS using a plugin. Sass will compile .sass and .scss files to .css files for you, so you can write your stylesheets with more advanced features. Note: the difference between using a .sass or .scss file is the syntax that you write your styles in.

What version of Webpack does Gatsby use?

If you’re upgrading from a previous Storybook version, be advised that Storybook relies on webpack 4, and Gatsby is currently supporting webpack 5. To update your Storybook version, run the following command:


2 Answers

install this npm package:

npm install sass-loader node-sass webpack --save-dev

and then in the .storybook folder create a file with webpack.config.js name and paste these configs on this file:

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          // Creates `style` nodes from JS strings
          'style-loader',
          // Translates CSS into CommonJS
          'css-loader',
          // Compiles Sass to CSS
          'sass-loader',
        ],
      },
    ],
  },
};
like image 186
Amir Jafari Avatar answered Oct 20 '22 21:10

Amir Jafari


I had this same problem.

I solved it by removing my styles.scss from my layout.js as this was causing errors due to not having loaders in Storybook. I then instead included styling in 2 separate locations, one for Gatsby and the other for Storybook which is now working well.


For Gatsby I have included styling in gatsby-browser.js as below:

import "./src/styles/styles.scss"

And for Storybook in .storybook/preview.js as:

import "!style-loader!css-loader!sass-loader!../src/styles.scss"

Adding loader support.


I think Amir Jafari's answer above should also work well.

I have used this method as I also use it to add support for the :focus-visible polyfill for visually testing components in Storybook so I feel this method can be useful for including other packages as well if a suitable Gatsby plugin is not (yet) available.

like image 1
Nikki Pantony Avatar answered Oct 20 '22 20:10

Nikki Pantony