Динамический импорт SVG-файлов в NextJS

#reactjs #svg #webpack #import #next.js

Вопрос:

Я пытаюсь динамически импортировать файлы SVG, которые мы используем для повышения производительности. Прямо сейчас мы используем статический импорт, и из-за этого он добавляет все svg файлы в HTML-сборку, даже если нам нужно всего несколько файлов на страницу. Это увеличивает время загрузки страницы, так как HTML файл больше, и поэтому загрузка и чтение HTML файла занимает больше времени, чем необходимо.

При текущей настройке страница сначала загружается, но затем отображается пустой экран. Причина , по которой он это делает, заключается в том, что он сначала загружает во <span/> время загрузки, а затем заменяет его на svg , но так как импорт не проходит хорошо, он выходит из строя и вместо этого показывает пустой экран.

Проект представляет собой проект NextJS, работающий с Webpack. Это код, который я использую для импорта SVG файлов:

 export const Chevron = dynamic(
  () => import('./Icons/chevron.svg'), 
    {
      loading: () => <span/>,
      ssr: false,
    }
  )
 

Ниже вы найдете ошибку, которую я получаю. Обратите внимание на < перед и /> за ним, что, по-видимому, указывает на то, что он пытается проанализировать base64 строку до a JSX.Element .

 Warning: <data:image/svg xml;base64,dmFyIF9wYXRoOwoKZnVuY3Rpb24gX2V4dGVuZHMoKSB7IF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTsgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0KCmltcG9ydCAqIGFzIFJlYWN0IGZyb20gInJlYWN0IjsKCmZ1bmN0aW9uIFN2Z0Fycm93U21hbGxVcChwcm9wcykgewogIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudCgic3ZnIiwgX2V4dGVuZHMoewogICAgeG1sbnM6ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsCiAgICB3aWR0aDogNiwKICAgIGhlaWdodDogMTMsCiAgICB2aWV3Qm94OiAiMCAwIDYgMTMiCiAgfSwgcHJvcHMpLCBfcGF0aCB8fCAoX3BhdGggPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudCgicGF0aCIsIHsKICAgIGZpbGw6ICIjRkZGIiwKICAgIGQ6ICJNMy4wNTUgMGEuMzY4LjM2OCAwIDAxLjE1NS4wNTNsLjA2Ny4wNTMgMi42MiAyLjYyYy4xMjUuMTI0LjE0Mi4zMTYuMDUyLjQ2bC0uMDU0LjA2Ny0uMDY4LjA1NGEuMzczLjM3MyAwIDAxLS4zOTIuMDAybC0uMDY3LS4wNTMtMS45ODQtMS45ODNoLS4wMzJ2MTAuNzYzYzAgLjE3LS4xMi4zMS0uMjc5LjM0M2wtLjA3LjAwN2EuMzUuMzUgMCAwMS0uMzQzLS4yOGwtLjAwNy0uMDctLjAwMS0xMC43NjNoLS4wMzFMLjYzOCAzLjI1NmEuMzcyLjM3MiAwIDAxLS40Ni4wNTFsLS4wNjctLjA1NGEuMzczLjM3MyAwIDAxLS4wMDMtLjUyN2wyLjYyLTIuNjJBLjM2Ny4zNjcgMCAwMTIuOTUxIDBoLjEwNHoiCiAgfSkpKTsKfQoKZXhwb3J0IGRlZmF1bHQgU3ZnQXJyb3dTbWFsbFVwOw== /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
 

Вот моя следующая конфигурация:

   const withFonts = require('next-fonts');
  const withTM = require('next-transpile-modules');

  module.exports = withTM(
    withFonts({
      useFileSystemPublicRoutes: false,
      enableSvg: true,
      webpack(config) {
        config.module.rules.push({
          test: /.svg$/,
          use: [
            {
              loader: '@svgr/webpack',
              options: {
                svgoConfig: {
                  plugins: {
                    removeViewBox: false,
                  },
                },
              },
            },
          ],
        });

        return config;
      },
      assetPrefix: '/_react',
      transpileModules: [
        'swiper',
        'dom7',
        'query-string',
        'strict-uri-encode',
        'split-on-first',
        'set-harmonic-interval',
      ],
    }),
  );
 

Комментарии:

1. Почему бы просто не использовать его таким import foo from 'path/to/foo.svg'; import Image from 'next/image'; ... <Image src={foo} /> образом, Также, пожалуйста, добавьте в вопрос свой веб-пакет/следующую конфигурацию и версию. То, что вы испытываете, не является поведением по умолчанию.

2. @brc-dd Я отредактировал свой вопрос с ответами, которые вы просили

3. next/dynamic используется для импорта компонентов React, но вы пытаетесь импортировать SVG. Попробуйте создать компонент, который отображает SVG, а затем динамически импортировать этот компонент вместо этого.