故事书:无法使用@ svgr / webpack

时间:2020-04-29 09:34:17

标签: javascript reactjs svg webpack storybook

首先,我的错误与所描述的here完全相同。我正在使用@svgr/webpack包将.svg文件作为React组件导入,如下所示:

import Shop from './icons/shop.svg'

return <Shop />

它在我的应用上正常运行,但是当我尝试在Storybook中执行相同操作时,出现此错误:

无法在“文档”上执行“ createElement”:提供的标签名称(“ static / media / shop.61b51e05.svg”)不是有效名称。

因此,我将加载程序添加到了.storybook/main.js文件中,以扩展默认的Storybook Webpack配置:

// ...
webpackFinal: async config => {    
    config.module.rules.push({
      test: /\.svg$/,
      enforce: 'pre',
      loader: require.resolve('@svgr/webpack'),
    });

该错误仍然发生,因此我尝试按照answer of the previous question中的建议为.svg文件覆盖默认的Storybook测试:

const fileLoaderRule = config.module.rules.find(rule => { rule.test !== undefined ? rule.test.test('.svg') : '' });
fileLoaderRule.exclude = /\.svg$/;

但随后出现此错误:

TypeError:无法设置未定义的属性“排除”

因此,我决定从console.log中抽取rule.test,奇怪的是,来自Storybook配置的唯一默认测试是这些:

{
  test: /\.md$/,
  ...
}
{
  test: /\.(js|mjs|jsx|ts|tsx)$/,
  ...
}
{
  test: /\.js$/,
  ...
}
{
  test: /\.(stories|story).mdx$/,
  ...
}
{
  test: /\.mdx$/,
  ...
}
{
  test: /\.(stories|story)\.[tj]sx?$/,
  ...
}
{
  test: /\.(ts|tsx)$/,
  ...
}

如您所见,没有任何测试会影响.svg文件。有人知道为什么我的配置无法使用:

{
  test: /\.svg$/, 
  enforce: 'pre',
  loader: require.resolve('@svgr/webpack'),
}

我的故事书版本为6.0.0-beta.3

2 个答案:

答案 0 :(得分:10)

您的find回调始终返回undefined。更改它以返回正确的布尔值:

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

通过此测试,任何故事书的默认配置都应具有图像规则: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/。 因此,您的代码(但带有正确的find回调)对我来说很好用。

最终main.js

module.exports = {
    stories: ['../src/**/*.stories.[tj]s'],
    webpackFinal: config => { 
        // Default rule for images /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/
        const fileLoaderRule = config.module.rules.find(rule => rule.test && rule.test.test('.svg'));
        fileLoaderRule.exclude = /\.svg$/;  

        config.module.rules.push({
          test: /\.svg$/,
          enforce: 'pre',
          loader: require.resolve('@svgr/webpack'),
        });

        return config;
    } 
};

答案 1 :(得分:0)

只需这样导入即可:

import { ReactComponent as Shop } from './icons/shop.svg'

它正在将其转换为React组件,以便您可以将属性传递给它:

<Shop fill="tomato" {...args} />