pd4d10 / vite-plugin-svgr

Vite plugin to transform SVGs into React components
MIT License
569 stars 54 forks source link

SVG export Errors after Upgrading vite-plugin-svgr from 3.x to 4.x #109

Open Phenek opened 9 months ago

Phenek commented 9 months ago

Issue with Upgrading vite-plugin-svgr from Version 3.3.0 to 4.2.0: SVG Import Errors

Description of the Issue

After updating vite-plugin-svgr from version 3.3.0 to 4.2.0, I am encountering an issue with importing SVG icons.

Previously, I exported all my SVG icons from an index.jsx file in my assets folder, which allowed for easy use with only one import and auto completion in my .tsx files.

Code Example

Here is how icons were exported in version 3.3.0:

// assets/images/index.jsx
export { ReactComponent as IconDownload } from "assets/images/icons/icon_download.svg";
export { ReactComponent as IconEye } from "assets/images/icons/icon_eye.svg";
export { ReactComponent as IconPause } from "assets/images/icons/icon_pause.svg";
export { ReactComponent as IconPlay } from "assets/images/icons/icon_play.svg";

And this is how I imported these icons in my .tsx components:

import { IconDownload, IconEye, IconPause, IconPlay } from "assets/images";

Encountered Problem

After updating to version 4.2.0, I am getting an import error in the index.jsx file, where I only do exports:

Uncaught SyntaxError: ambiguous import: IconDownload index.jsx:2:10

Attempts to Resolve

I have spent approximately a day trying to resolve this issue. I have reviewed the documentation and searched for similar cases online, but I haven't found anything that exactly matches my problem.

export MyIcon from "../MyIcon.svg";  // with or without `?react`

Request for Assistance

Could you please guide me towards a solution or provide insights on what might be causing this issue? I don't want to lost my one line import with auto completion. Thank you in advance for your help and guidance.

IgorSkvortsov commented 9 months ago

Hello, had a same problem and wasted lots of time searching for possible solutions.

Using:

"vite": "^5.0.0", "vite-plugin-svgr": "^4.2.0".

What really helped me is removing old index.d.ts for .svg files (for TS):

declare module '*.svg' {
  import * as React from 'react'

  export const ReactComponent: React.FunctionComponent<
    React.ComponentProps<'svg'> & { title?: string }
  >
  export default ReactComponent
}

Next step is changing index file with exports from:

export { ReactComponent as Icon } from './icon.svg';

to:

export { default as Icon } from './icon.svg?react';

I believe it's not the best solution, but at least it works for me (imports work fine too).

adeel-ali-atp commented 9 months ago

Not working

Phenek commented 9 months ago

Hey, my workaround was to use @svgr/rollup vite.config.js

import svgr from "@svgr/rollup";
...
export default defineConfig({
...
plugins: [
    svgr({ dimensions: false, svgo: false, typescript: true }),
    ...
  ],
  ...
  });

I let the custom.d.ts

declare module "*.svg" {
  import * as React from "react";

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >;

  export default ReactComponent;
}

And my index.tsx as usual

export { ReactComponent as IconDownload } from "assets/images/icons/icon_download.svg";
export { ReactComponent as IconEye } from "assets/images/icons/icon_eye.svg";
export { ReactComponent as IconPause } from "assets/images/icons/icon_pause.svg";
export { ReactComponent as IconPlay } from "assets/images/icons/icon_play.svg";
adeel-ali-atp commented 9 months ago

export IconPlay from "assets/images/icons/icon_play.svg?react";

worked for me. It returns react component

skkaushik21 commented 9 months ago

export IconPlay from "assets/images/icons/icon_play.svg?react";

worked for me. It returns react component

It works but if you are using jest and react testing library for testing. It doesn't find the module (file) with the path ends with ?react and the test case fails.

DieTapete commented 8 months ago

This worked for me in combination with the above mentioned custom.d.ts: https://github.com/pd4d10/vite-plugin-svgr/issues/107#issuecomment-1969337293

jwalkerinterpres commented 7 months ago

Doesn't work for me, even in combination of the above mentioned custom.d.ts changes.

Phenek commented 7 months ago

Under the hood vite-plugin-svgr use "@svgr/core", "@rollup/pluginutils" all this come from the react-svgr team

So please use directly their rollup plugin described here: https://react-svgr.com/docs/rollup/

To make no difference between vite-plugin-svgr and @rollup/svgr use it like follow in the vite.config.js: vite.config.js

import svgr from "@svgr/rollup";
...
export default defineConfig({
...
plugins: [
    svgr({ dimensions: false, svgo: false, typescript: true }),
    ...
  ],
  ...
  });

and like before:

I let the custom.d.ts

declare module "*.svg" {
  import * as React from "react";

  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement> & { title?: string }
  >;

  export default ReactComponent;
}

And my index.tsx as usual

export { ReactComponent as IconDownload } from "assets/images/icons/icon_download.svg";
export { ReactComponent as IconEye } from "assets/images/icons/icon_eye.svg";
export { ReactComponent as IconPause } from "assets/images/icons/icon_pause.svg";
export { ReactComponent as IconPlay } from "assets/images/icons/icon_play.svg";