Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Storybook not displaying SVG icons

I am not able to see the SVG icons in Storybook. I am new to front-end development so not sure what I am doing wrong. I referred to this article https://medium.com/@derek_19900/config-storybook-4-to-use-svgr-webpack-plugin-22cb1152f004. Here is file webpack.config.js

const path = require('path');

const rootDir = path.resolve(__dirname, '../src');

const pathToInlineSvg = path.resolve(__dirname, '../src/assets/images/icons');

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

  const fileLoaderRule = config.module.rules.find(rule => rule.test.test('.svg'));
  fileLoaderRule.exclude = pathToInlineSvg;

  config.module.rules = config.module.rules.map(rule => {
    if (rule.exclude && rule.test.test('styles.scss')) {
      rule.use = rule.use.map(use => {
        if (use && use.loader && use.loader.indexOf('sass-loader') !== -1) {
          use.options.data = `
            @import "@/assets/styles/theme.scss";
            @import "@/assets/styles/fonts.scss";
          `;
        }
        return use;
      });
    }
    return rule;
  });

  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: require.resolve('babel-loader'),
    options: {
      presets: [['react-app', { flow: false, typescript: true }]],
    },
  });

  config.module.rules.push({
    test: /\.(jsx)$/,
    loader: require.resolve('babel-loader'),
    options: {
      presets: ["@babel/preset-env", "@salesforce/babel-preset-design-system-react"],
    },
  });

  config.module.rules.push({
    test: /\.svg$/,
    include: pathToInlineSvg,
    use: [{loader: '@svgr/webpack',
              options: {
                icon: true,
              },
          }
    ],
  });

  config.resolve.extensions.push('.ts', '.tsx', '.svg');
  config.resolve.alias['@'] = rootDir;

  return config;
};
like image 398
NewQueries Avatar asked Mar 04 '23 05:03

NewQueries


1 Answers

SVGs are not loading into Storybook in your setup because Storybook’s default webpack config already has a .svg loader, and is using file-loader.

See Line 65 - Line 68 of Storybook base-webpack.config.js

If you want to use @svgr/webpack loader, you need to write a custom webpack config so that the @svgr/webpack loader rule is before the file-loader.

This webpack config rule adds the @svgr/webpack loader before any other asset loaders:

  // Add SVGR Loader
  // ========================================================
  // Remove svg rules from existing webpack rule
  const assetRule = config.module.rules.find(({ test }) => test.test('.svg'));

  const assetLoader = {
    loader: assetRule.loader,
    options: assetRule.options || assetRule.query,
  };

  config.module.rules.unshift({
    test: /\.svg$/,
    use: ['@svgr/webpack', assetLoader],
  });

You can see a complete webpack.config.js in this Gatsby starter (Gatsby + TypeScript + Emotion + Storybook)

like image 127
Duncan Avatar answered Mar 06 '23 22:03

Duncan