React Storybook SVG Не удалось выполнить createElement для документа - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь добавить Storybook в существующее приложение React, но получаю ошибки с импортированными файлами SVG. SVG импортируется и используется как:

import Border from './images/border.inline.svg'
...
<Border className="card__border" />

Это работает, когда приложение запускается и собирается, но я получаю сообщение об ошибке в Storybook. Как получилось?


Failed to execute 'createElement' on 'Document': The tag name provided ('static/media/border.inline.258eb86a.svg') is not a valid name.
Error: Failed to execute 'createElement' on 'Document': The tag name provided ('static/media/border.inline.258eb86a.svg') is not a valid name.

По умолчанию webpack.config.js имеет:

  ...
  {
    test: /\.inline.svg$/,
    loader: 'svg-react-loader'
  },
  ...

Кроме того, существующий код использует webpack 3, а я использую Storybook V4.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Я получил это работает с

...
module.exports = {
  module: {
    rules: [
      {
        test: /\.inline.svg$/,
        loader: 'svg-react-loader'
      }
    ]
  }
}
0 голосов
/ 21 января 2019

Это происходит из-за того, что стандартная конфигурация веб-пакета Storybook имеет собственную конфигурацию svg:

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

Я почти уверен, что это причина, потому что вы можете увидеть путь, обозначенный в сообщении об ошибке: query: { name: 'static/media/[name].[hash:8].[ext]' } -> static/media/border.inline.258eb86a.svg

Решением может быть нахождение существующего загрузчика и изменение / или добавление к нему правила исключения. Вот пример пользовательского .storybook/webpack.config.js:

// storybook 4
module.exports = (_, _, config) => {
// storybook 5
module.exports = ({ config }) => {
  const rules = config.module.rules;

  // modify storybook's file-loader rule to avoid conflicts with your inline svg
  const fileLoaderRule = rules.find(rule => rule.test.test('.svg'));
  fileLoaderRule.exclude = /\.inline.svg$/;

  rules.push({
    test: /\.inline.svg$/,
    ...
    }],
  });

  return config;
};
...