Сборник рассказов: не удалось выполнить createElement для файлов SVG с помощью @ svgr / webpack - PullRequest
4 голосов
/ 29 апреля 2020

Во-первых, моя ошибка точно такая же, как и описанная здесь . Я использую пакет @ svgr / webpack для импорта моих .svg файлов в качестве компонента React, например:

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

return <Shop />

Он отлично работает в моем приложении, но когда я пытался сделать то же самое в Сборник рассказов Я получаю эту ошибку:

Не удалось выполнить «createElement» для «Документа»: предоставлено имя тега («static / media / shop.61b51e05. svg ') не является допустимым именем.

Поэтому я добавил загрузчик в свой файл .storybook/main.js, чтобы расширить конфигурацию веб-пакета Storybook по умолчанию:

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

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

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

Но тогда я получаю эту ошибку:

TypeError: Невозможно установить свойство 'exclude' из неопределенного

Поэтому я решил сделать 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'),
}

1 Ответ

0 голосов
/ 10 мая 2020

Ваш find обратный вызов всегда возвращает undefined. Измените его, чтобы он возвращал правильное значение bool:

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) отлично работает для меня.

Final 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;
    } 
};
...