1

I been struggling with this for a week, I been reading another Stackoverflow questions and the SVGR/WEBPACK documentation but I'm unable to solve this.

I wanted to upgrade an old react single-spa application but it had a lot of conflicting dependencies so I simply went and created a new one using the Single Spa Playground web application, everything works great but I can't get my SVG'S as React Components with SVGR/WEBPACK.

The error:

enter image description here

webpack.config.js

const webpackMerge = require("webpack-merge").merge;
const singleSpaDefaults = require("webpack-config-single-spa-react-ts");

module.exports = (webpackConfigEnv, argv) => {
  const defaultConfig = singleSpaDefaults({
    orgName: "testorg",
    projectName: "testproj",
    webpackConfigEnv,
    argv,
  });

  return webpackMerge(defaultConfig, {
    module: {
      rules: [
        {
          test: /\.s[ac]ss$/i,
          use: ["style-loader", "css-loader", "sass-loader"],
        },
        {
          test: /\.svg$/,
          use: ["@svgr/webpack"],
        },
      ],
    },
  });
};

How I'm importing the svg

import TestImg from "../../assets/icons/testimage.svg";

How I'm using the SVG

<TestImg /> 

declarations.d.ts

I'm not entirely sure how does this works but I also removed this and it's the same.

declare module "*.svg" {
  const content: React.FC<React.SVGAttributes<SVGElement>>;
  export default content;
}

package.json

{
  "name": "@testorg/testproj",
  "scripts": {
    "start": "webpack serve",
    "start:standalone": "webpack serve --env standalone",
    "build": "concurrently npm:build:*",
    "build:webpack": "webpack --mode=production",
    "analyze": "webpack --mode=production --env analyze",
    "lint": "eslint src --ext js,ts,tsx",
    "format": "prettier --write .",
    "check-format": "prettier --check .",
    "test": "cross-env BABEL_ENV=test jest",
    "watch-tests": "cross-env BABEL_ENV=test jest --watch",
    "prepare": "husky install",
    "coverage": "cross-env BABEL_ENV=test jest --coverage",
    "build:types": "tsc"
  },
  "devDependencies": {
    "@babel/core": "^7.15.0",
    "@babel/eslint-parser": "^7.15.0",
    "@babel/plugin-transform-runtime": "^7.15.0",
    "@babel/preset-env": "^7.15.0",
    "@babel/preset-react": "^7.14.5",
    "@babel/preset-typescript": "^7.15.0",
    "@babel/runtime": "^7.15.3",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^12.0.0",
    "@types/testing-library__jest-dom": "^5.14.1",
    "babel-jest": "^27.0.6",
    "concurrently": "^6.2.1",
    "cross-env": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-ts-react-important-stuff": "^3.0.0",
    "eslint-plugin-prettier": "^3.4.1",
    "husky": "^7.0.2",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^27.0.6",
    "jest-cli": "^27.0.6",
    "prettier": "^2.3.2",
    "pretty-quick": "^3.1.1",
    "sass": "^1.56.2",
    "sass-loader": "^13.2.0",
    "ts-config-single-spa": "^3.0.0",
    "typescript": "^4.3.5",
    "webpack": "^5.75.0",
    "webpack-cli": "^4.8.0",
    "webpack-config-single-spa-react": "^4.0.0",
    "webpack-config-single-spa-react-ts": "^4.0.0",
    "webpack-config-single-spa-ts": "^4.0.0",
    "webpack-dev-server": "^4.0.0",
    "webpack-merge": "^5.8.0"
  },
  "dependencies": {
    "@datepicker-react/hooks": "^2.8.4",
    "@svgr/webpack": "^6.5.1",
    "@types/jest": "^27.0.1",
    "@types/react": "^17.0.19",
    "@types/react-dom": "^17.0.9",
    "@types/systemjs": "^6.1.1",
    "@types/webpack-env": "^1.16.2",
    "date-fns": "^2.29.3",
    "prop-types": "^15.8.1",
    "react": "^17.0.2",
    "react-datepicker": "^4.8.0",
    "react-dom": "^17.0.2",
    "react-modal": "^3.16.1",
    "react-number-format": "^5.1.2",
    "react-toastify": "^6.2.0",
    "single-spa": "^5.9.3",
    "single-spa-react": "^4.3.1",
    "styled-components": "^5.3.6"
  },
  "types": "dist/testorg-testproj.d.ts"
}

The only way it works

The only way I got it working is uninstalling @svgr/webpack and using my imported svg inside of an img tag, as a source.

<img src={TestImg} alt='' width='200' height='200' />

But is not what I want, I need to be able modify the svg fill by props and that's why I need it as a React Component.

Also, I have a LOT of icons and logos in this project, so manually creating a React Component in my project for each image/icon it's not the solution I'm looking for.

Additional information 1

I put a console log for the TestImg and it shows an url, clearly it's not importing it as a component

If I go to the url this is what it shows: enter image description here

Additional information 2

import { ReactComponent as TestImg } from "../../assets/icons/testimage.svg"

Doesn't work either, it says:

Can't import the named export 'ReactComponent' (imported as 'TestImg') from default-exporting module (only default export is available)

  • I was experiencing the exact same situation with Webpack and SVGR in a React project this week, specifically when running Storybook and loading any component which imported SVGs in the same way. The project was originally created with Create React App. In my case the issue was presenting because one of the dependencies was ALSO handling SVGs, overwriting the config I was pushing into Webpack. So that might be a good place for you to start, determining if any of the other dependencies you have are handling SVGs too. – Rich Jan 12 '23 at 16:18

0 Answers0