Búsqueda de sitios web

reactjs - Jest no puede encontrar el módulo con ".svg?react" Vite + React + Ts + Jest


Estoy intentando probar mi aplicación hecha con vite + react + ts, pero cuando quiero crear mi componente de panel de control, jest se queja de que no puede encontrar el módulo "svg?react".

Este es el problema con Jest cuando inicio la prueba

Cannot find module './brand.svg?react' from 'src/sections/dashboard/Dashboard.tsx'

Este es mi vite.config.ts

import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import dotenv from "dotenv";
import svgr from 'vite-plugin-svgr'

dotenv.config();
export default defineConfig((configEnv) => {
    const isDevelopment = configEnv.mode === "development";

    return {
        plugins: [react(), svgr()],
        css: {
            modules: {
                generateScopedName: isDevelopment ? "[name]__[local]__[hash:base64:5]" : "[hash:base64:5]",
            },
        },
        define: {
            "process.env": process.env,
        },
    };
});

Este es mi jest.config.js

module.exports = {
    testEnvironment: "jsdom",
    setupFilesAfterEnv: ["<rootDir>/tests/setupTests.ts"],
    testMatch: ["<rootDir>/tests/**/*.(test).(ts|tsx)"],
    testPathIgnorePatterns: ["<rootDir>/tests/e2e/"],
    transform: {
        "^.+\\.(js|jsx|ts|tsx)$": [
            "@swc/jest",
            {
                sourceMaps: true,
                jsc: {
                    parser: {
                        syntax: "typescript",
                        tsx: true,
                    },
                    transform: {
                        react: {
                            runtime: "automatic",
                        },
                    },
                },
            },
        ],
    },
    moduleNameMapper: {
        "\\.(svg$|svg?react)": "<rootDir>/tests/svg.mock.js",
        "\\.(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",
    },
};

Este es mi svg.mock.js

/* eslint-disable import/no-anonymous-default-export */
export default "SvgrURL";
export const ReactComponent = "div";

Anteriormente, busqué cómo resolver el problema de Vite con SVG usando vite-plugin-svgr y funcionó, pero ahora esto genera conflictos con Jest. Estoy realmente atascado con esto, pero con CRA esto no ocurre.

Respuesta #1

Se me ha ocurrido otra idea.

  1. Agrega moduleNameMapper para ayudar a jest a manejar esta sintaxis de importación: .svg?react. Convierte importaciones como ./icons/myIcon.svg?react a ./icons/myIcons.svg
  moduleNameMapper: {
    '^(.*).svg\\?react$': '$1.svg',
  }
  1. Agrega el transformador jest-transformer-svg. '^.+\\.svg(\\?react)?$' - usa 'jest-transformer-svg' para las importaciones normales de .svg y también .svg?react.
  transform: {
    '^.+\\.svg(\\?react)?$': 'jest-transformer-svg',
  },

Con esta configuración los SVG se renderizan así:

<svg
   class="opt-icon icon iconSmall moreIcon"
   data-file-name="SvgMore_vert24px"
/>

Respuesta #2

Me enfrenté a una situación similar. Lo que me funcionó

//svgr-mock.js
const SvgComponent = (props) => {
  return React.createElement('svg', {
    ...props,
    'data-testid': 'svg-mock',
  });
};
module.exports = SvgComponent;
module.exports.ReactComponent = SvgComponent; 
//jest-config.js
const config: Config = {
  roots: ['<rootDir>/src'],
  verbose: true,
  testEnvironment: 'jest-environment-jsdom',
  modulePaths: ['<rootDir>/src'],
  setupFilesAfterEnv: ['@testing-library/jest-dom', '<rootDir>/src/tests/setup/setup-tests.ts'],
  transform: {
    '^.+\\.(js|jsx)$': 'babel-jest',
    '^.+\\.(ts|tsx)$': 'ts-jest',
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|svg|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/src/tests/setup/file-transform.js',
  },
  moduleNameMapper: {
    '\\.svg\\?react$': '<rootDir>/src/tests/setup/svgr-mock.js',
    '\\.(css|scss)$': '<rootDir>/src/tests/setup/style-mock.js',
  },
  transformIgnorePatterns: [
    '[/"\]node_modules[/"\].+\\.(js|jsx|mjs|cjs|ts|tsx)$',
    '^.+\\.module\\.(css|sass|scss)$',
  ],
  testMatch: ['<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}', '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'],
  resetMocks: true,
};

export default config;

Si eso no funciona, ¿podrías también proporcionar tu configuración de Babel?

Artículos relacionados