故事书:无法使用 @svgr/webpack 对 svg 文件执行“createElement”

joh*_*pin 11 javascript svg reactjs webpack storybook

我的错误首先与此处描述的错误完全相同。我正在使用@svgr/webpack包将我的.svg文件作为这样的 React 组件导入:

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

return <Shop />
Run Code Online (Sandbox Code Playgroud)

它在我的应用程序上运行良好,但是当我尝试在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'),
    });
Run Code Online (Sandbox Code Playgroud)

错误仍然发生,因此我尝试按照上一个问题.svg答案中的建议覆盖文件的默认 Storybook 测试:

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

但是后来我收到了这个错误:

类型错误:无法设置未定义的属性“排除”

所以,我决定做一个console.logrule.test和奇怪的故事书,从未来配置的唯一默认的测试论文:

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

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

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

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

Max*_*nev 23

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

const fileLoaderRule = config.module.rules.find(rule => rule.test && rule.test.test('.svg'));
Run Code Online (Sandbox Code Playgroud)

不管怎样,故事书的默认配置应该有一个规则来处理这个测试的图像: /\.(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;
    } 
};
Run Code Online (Sandbox Code Playgroud)