Проблема с компонентом рендеринга, созданная с использованием vite-plugin-svgr в шуточном тесте с использованием метода рендеринга библиотеки тестирования/реагирования

Я разрабатываю приложение React, используя среду разработки Vite. Поскольку Vite хорошо поддерживается, я включил несколько плагинов, которые довольно хорошо с ним работают, в частности тот, который дает мне возможность создавать компоненты, напрямую импортирующие *.svg в определенном формате. Он называется vite-plugin-svgr, и вы можете создать компонент следующим образом, просто включив ?react в конце:

import Lock from '../assets/icons/lock.svg?react'

Как только я это сделал, я начал разрабатывать несколько тестов с помощью Jest и test-library/react, и похоже, что методу «рендеринг» из test-library/react не нравится, как компоненты создаются с помощью плагина.

В основном выдает следующую ошибку: `console.error Предупреждение: React.jsx: тип недействителен — ожидалась строка (для встроенных компонентов) или класс/функция (для составных компонентов), но получен: объект.

    Check the render method of `Widget`.
        at repositoryData (/Users/joscormir/Dev/dashboard_project/src/components/Widget.jsx:13:26)
        at section
        at Dashboard (/Users/joscormir/Dev/dashboard_project/src/components/Dashboard.jsx:9:61)
    
      24 |           {repositoryData.organization.login}/{repositoryData.name}
      25 |         </a>
    > 26 |         {repositoryData.private ? <Lock /> : <UnLock />}
         |                                              ^
      27 |       </header>
      28 |
      29 |       <div className = {styles.widget__body}>`

Учтите, что <UnLock /> — это компонент, созданный описанным ранее способом: import UnLock from '../assets/icons/unlock.svg?react' и Widget.jsx — это компонент, включающий компонент <UnLock />.

У него явно проблемы с рендерингом этого компонента.

Поскольку это довольно просто, я подумал об использовании плагина Jest под названием jest-transformer-svg

import React from 'react';
import MySvg from '../images/an-image.svg';

function MyComponent() {
  return (
    <div>
      <MySvg style = {{ color: 'blue' }} />
    </div>
  );
}

Затем, поскольку расширение моих файлов немного отличается, я попытался использовать Jest для преобразования расширения, чтобы соответствовать требованиям приведенного выше примера, включая следующее предложение в моем файле.

\*.svg?react

Но это не сработало. Весь тестовый комплект не работает, поскольку он говорит, что теперь не может найти модуль, объявленный с расширениями jest.config.js\, что означает, что '^.+\\.(svg\\?react)$': 'jest-transformer-svg' не совсем работает, насколько я понимаю.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
483
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я нашел способ заставить это работать. Он работает как шарм, и я нашел его, прочитав вопросы в vite-plugin-svgr. Ключевым моментом здесь является замена расширения .svg?react на .svg. Это возможно, изменив способ включения vite.config.jsвызова плагина.

Нам нужно изменить его следующим образом:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import svgr from 'vite-plugin-svgr'

export default defineConfig({
  plugins: [react(), svgr({ include: '**/*.svg' })],
})

Ключевым моментом является то, как мы подключаем файлы svg. С помощью этой модификации мы можем изменить способ импорта компонентов с использования UnLock from '../assets/icons/unlock.svg?react' на использование UnLock from '../assets/icons/unlock.svg'.

Благодаря этой модификации мы теперь можем правильно использовать jest-transformer-svg, поскольку он будет правильно интерпретировать файлы .svg, включая в файл jest.config.js правило преобразования, сообщающее преобразователю jest преобразовать все файлы с этими расширениями '^.+\\.svg$': 'jest-transformer-svg':

module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/tests/setupTests.js'],
  testMatch: ['<rootDir>/tests/**/*.(test).(js|jsx)'],
  testPathIgnorePatterns: ['<rootDir>/tests/e2e/'],
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': [
      '@swc/jest',
      {
        sourceMaps: true,
        jsc: {
          parser: {
            syntax: 'ecmascript',
            jsx: true,
          },
          transform: {
            react: {
              runtime: 'automatic',
            },
          },
        },
      },
    ],
    '^.+\\.svg$': 'jest-transformer-svg',
  },
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      'jest-transform-stub',
  },
}

Выше приведены мои файлы конфигурации, которыми я поделился только для того, чтобы уточнить, где должно быть размещено правило преобразования, все остальное может измениться в зависимости от вашей собственной конфигурации jest.

Вы можете издеваться над файлами SVG

  "jest": {
    "moduleNameMapper": {
      "\\.svg\\?(react|url)$": "<rootDir>/src/__mocks__/svgMock.js"
    }
  },

src/mocks/svgMock.js

const SvgMock = (props) => {
  return (
    <svg {...props}>
      <title>Mock SVG</title>
    </svg>
  )
}

export default SvgMock

Другие вопросы по теме

Похожие вопросы

Асинхронные проблемы с useState в React Hooks
Ошибка: только простые объекты и несколько встроенных функций могут быть переданы клиентским компонентам из серверных компонентов. Классы или нулевые прототипы не поддерживаются
Как дождаться завершения вызовов API, прежде чем создавать еще один, когда они находятся в своих собственных функциях?
Eslint – невозможно разрешить путь к модулю @web3modal/ethers/react, import/no-unresolved
Сбой подключения NodeJS к CosmosDB при создании клиента из строки подключения
Как применить разные стили для многоразовой кнопки реагирования с помощью Mui
Как запустить повторный рендеринг компонента реагирования после изменения параметра запроса (без реагирования-маршрутизатора)
Медленный запуск vite с булочкой
Страница не перенаправляется должным образом, как решить
Приложение Node.js v20.12.2 [nodemon] вылетело из строя – перед запуском ожидается изменение файла