Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG loader returns a string instead of a symbol object when loading from storybook #267

Closed
silicakes opened this issue Mar 29, 2018 · 5 comments

Comments

@silicakes
Copy link

versions:

    "svg-sprite-loader": "^3.7.3",
    "svgo": "^1.0.5",
    "svgo-loader": "^2.1.0",
    "ts-loader": "^4.1.0",
    "typescript": "^2.8.1",
    "webpack": "^4.3.0",
    "webpack-cli": "^2.0.13"

webpack configuration

{
    test: /\.svg$/,
    use: [
      {
        loader: 'svg-sprite-loader',
        options: {
          // extract: true,
          spriteFilename: "icon.svg"
        }
      }, {
        loader: 'svgo-loader',
        options: {
          plugins: [
            { removeTitle: true },
            { convertColors: { shorthex: false } },
            { convertPathData: false }
          ]
        }
      }]
  }

When importing a sprite:

import * as education from "../src/assets/svg/education.svg";

instead of getting a symbol object as depicted here, I'm getting a url in the form of:

/static/media/education.3a3782a8.svg

I can't seem to find the reason causing it.
Thanks in advance.

@kisenka
Copy link
Contributor

kisenka commented Mar 29, 2018

Could you please create repo with minimal setup to demonstrate a problem (package.json, webpack config, SVG image and piece of your code). If you don't want to create a repository - you can create a gist with multiple files.

@silicakes
Copy link
Author

silicakes commented Mar 30, 2018

@kisenka I've failed to reproduce it on a new repo as the issue was directly connected to storybook.

For future references, storybook uses file-loader to load most of its assets - including svg:

/node_modules/@storybook/react/dist/server/config/defaults/webpack.config.js

{
    test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
    include: _utils.includePaths,
    loader: require.resolve('file-loader'),
    query: {
      name: 'static/media/[name].[hash:8].[ext]'
    }
  }

my workaround was to override the default rule set by applying my loaders directly onto their webpack override module, located under .storybook/webpack.config.js:

const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

module.exports = (baseConfig, env) => {
  const config = genDefaultConfig(baseConfig, env);

  //overriding configs rule set rather than pushing additional rules to it
  config.module.rules = [{
    test: /\.(ts|tsx)$/,
    loader: require.resolve('ts-loader')
  },{
    test: /\.svg$/,
    use: [
      {
        loader: 'svg-sprite-loader',
        options: {
          extract: true,
          spriteFilename: "icon.svg"
        }
      }, {
        loader: 'svgo-loader',
        options: {
          plugins: [
            { removeTitle: true },
            { convertColors: { shorthex: false } },
            { convertPathData: false }
          ]
        }
      }]
  }];
  config.plugins.push(new SpriteLoaderPlugin());
  config.resolve.extensions.push('.ts', '.tsx');
  return config;
};

Thanks!

@silicakes silicakes changed the title BUG - SVG loader returns string instead of symbol object BUG - SVG loader returns string instead of symbol object when loading from storybook Mar 30, 2018
@silicakes silicakes changed the title BUG - SVG loader returns string instead of symbol object when loading from storybook SVG loader returns string instead of symbol object when loading from storybook Mar 30, 2018
@silicakes silicakes changed the title SVG loader returns string instead of symbol object when loading from storybook SVG loader returns a string instead of a symbol object when loading from storybook Mar 30, 2018
@Under-Warz
Copy link

@silicakes and futher readers, I resolved my issue with overriding svg loader in storybook with this answer storybookjs/storybook#6758 (comment)

@Pet3ris
Copy link

Pet3ris commented Jan 28, 2021

This is the full implementation if someone is interested:

  config.module.rules = config.module.rules.map(rule => {
    if (rule.test.toString().includes('svg')) {
      const test = rule.test.toString().replace('svg|', '').replace(/\//g, '')
      return { ...rule, test: new RegExp(test) }
    } else {
      return rule
    }
  });

  config.module.rules.push(
    {  
      test: /\.svg$/i,
      loader: require.resolve('svg-sprite-loader')
    }
  );

@dskline
Copy link

dskline commented Jun 7, 2021

Probably due to a recent update, one of the webpack rules in the default storybook config has a rule.test that returns undefined now. I made a small tweak to the if statement:

  config.module.rules = config.module.rules.map((rule) => {
    if (rule.test && rule.test.toString().includes("svg")) {
      const test = rule.test.toString().replace("svg|", "").replace(/\//g, "");
      return { ...rule, test: new RegExp(test) };
    } else {
      return rule;
    }
  });

  config.module.rules.push({
    test: /\.svg$/,
    loader: require.resolve("svg-sprite-loader"),
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants