pd4d10 / vite-plugin-svgr

Vite plugin to transform SVGs into React components
MIT License
522 stars 55 forks source link

Plugins don't work #7

Open worlddai opened 3 years ago

worlddai commented 3 years ago

40/5000 I'm having a problem. Your plug-in doesn't work after using it. I don't know what's wrong with the configuration. The browser returned the following error:

Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('/src/images/smcLogo.svg') is not a valid name.

my code is this:

import React, { Component } from 'react';
import cssObj from './Logo.css';
import Icon from '@ant-design/icons';
import {ReactComponent as SMCLogo } from '@/images/smcLogo.svg';
class Logo extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (

            <div style={{width: this.props.width, height: this.props.height, paddingTop:'10px' }} >
                <div className={cssObj.LogoLeft}>
                    <Icon component={()=><SMCLogo width="70px" height="22px"  fill="#B7C1CF"/>} />
                </div>
            </div>

        );
    }
}

export default Logo;

Looking forward to your reply. thank you

pd4d10 commented 2 years ago

Thanks for the report. Could you provide a minimal reproduce repo?

yckbilly1929 commented 2 years ago

same error after updating svgr related dependencies to 6.1.2

alkanna commented 2 years ago

I'm having an issue here too where my svg files are not optimized by svgo at all. Here's the config

svgrPlugin({
      svgrOptions: {
        svgo: true,
        icon: false,
        svgoConfig: {
          plugins: [
            { moveGroupAttrsToElems: true },
            { convertPathData: true },
          ],
        },
      },
    })],
FDiskas commented 2 years ago

latest svgo changed his default configuration format from yml to js. So that could be a issue.

fatso83 commented 2 years ago

This is missing a reproduction step. Something similar happened when I tried setting up the webpack config for Storybook to work with the @webpack/svgr. Turns out the default webpack config setup for Storybook had fileloader rules that hit the *.svg and returned the path before my svgr config was hit. So there was no ReactComponent to use. I had to dynamically replace the regex to be able to override what to do with the svgs. Might be something similar going on here, seeing that Vite handles svg loading as paths by default. Don't see how, though, as it works fine for me :shrug:

JiangWeixian commented 1 year ago

@alkanna I meet same issue, I fix my issue by by add @svgr/plugin-svgo and @svgr/plugin-jsx, see https://github.com/pd4d10/vite-plugin-svgr/issues/49 for more details

javaharut commented 1 year ago

I am facing the issue where svgo config is setup but svg components get rendered as it is without any optimisation. I have tried above mentioned ways but still no success.

fatso83 commented 1 year ago

I suggest everyone having trouble to just fire up a debugger to see what is going on. This makes it quite clear without waiting for anyone else to figure it out (which is not likely to happen).

Just

  1. Figure out which plugins are loaded in which order
  2. Open up the plugin modules in node_modules in your editor and put breakpoints in them, or insert debugger statements
  3. Figure out how to run Vite inside your debugger (open node_modules/.bin/vite to see)
  4. Profit
javaharut commented 1 year ago

I figured out and it seems working as a pie. here is full config which will make things better for newcomers

svgr({
      svgrOptions: {
        plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx'],
        svgoConfig: {
          plugins: ['preset-default', 'removeTitle', 'removeDesc', 'removeDoctype', 'cleanupIds'],
        },
      },
    }),
pcfreak30 commented 12 months ago

I have been trying to use this and debugged the code both with exportAsDefault on and off. The code generates fine, but I end up with this in the bundle:

function Footer({ connected }) {
  return /* @__PURE__ */ React.createElement("div", { className: classNames("socials", { connected }) }, /* @__PURE__ */ React.createElement("a", { href: "#", title: "GitHub", className: "github-logo" }, /* @__PURE__ */ React.createElement("svgGithub", null)), /* @__PURE__ */ React.createElement("a", { href: "#", title: "Discord", className: "discord-logo" }, /* @__PURE__ */ React.createElement("svgDiscord", null)), /* @__PURE__ */ React.createElement("a", { href: "#", title: "Twitter", className: "twitter-logo" }, /* @__PURE__ */ React.createElement("svgTwitter", null)), /* @__PURE__ */ React.createElement("a", { href: "#", title: "Facebook", className: "facebook-logo" }, /* @__PURE__ */ React.createElement("svgFacebook", null)));
}

this is on the classic react mode react({ jsxRuntime: "classic" }),

in the default mode:

function Footer({ connected }) {
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classNames("socials", { connected }), children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#", title: "GitHub", className: "github-logo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svgGithub", {}) }),
    /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#", title: "Discord", className: "discord-logo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svgDiscord", {}) }),
    /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#", title: "Twitter", className: "twitter-logo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svgTwitter", {}) }),
    /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#", title: "Facebook", className: "facebook-logo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svgFacebook", {}) })
  ] });
}

JSX Code is:

import "./Footer.scss";
import classNames from "classnames";
import svgGithub from "../../../assets/icon/github.svg";
import svgDiscord from "../../../assets/icon/discord.svg";
import svgTwitter from "../../../assets/icon/twitter.svg";
import svgFacebook from "../../../assets/icon/facebook.svg";

export default function Footer({ connected }) {
  return (
    <div className={classNames("socials", { connected })}>
      <a href="#" title="GitHub" className="github-logo">
        <svgGithub />
      </a>
      <a href="#" title="Discord" className="discord-logo">
        <svgDiscord />
      </a>
      <a href="#" title="Twitter" className="twitter-logo">
        <svgTwitter />
      </a>
      <a href="#" title="Facebook" className="facebook-logo">
        <svgFacebook />
      </a>
    </div>
  );
}
fatso83 commented 11 months ago

@pcfreak30 You are not actually stating what your problem with the generated code is, so hard to help you out 😄

pcfreak30 commented 11 months ago

Sorry thought it was obvious.

jsxRuntimeExports.jsx("svgGithub", {}) }),

React.createElement("svgFacebook", null)

The element isn't actually created, its null/empty.

antekai commented 10 months ago

I had the same problem as I didn't notice latest breaking change of V4

If you use the latest version vite-plugin-svgr (v4), you have to update the import syntax as follows

### before
import { ReactComponent as Logo } from "./logo.svg";

## after
import Logo from "./logo.svg?react";
zzswang commented 10 months ago

using svgr in electron and vite, same problem, warning like:

react-dom.development.js:26923 Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('/src/aa.svg?react') is not a valid name.
    at createElement (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:7509:42)
    at createInstance (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:8345:28)
    at completeWork (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:16277:34)
    at completeUnitOfWork (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:19215:24)
    at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:19200:13)
    at workLoopSync (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:19131:13)
    at renderRootSync (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:19110:15)
    at recoverFromConcurrentError (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:18730:28)
    at performConcurrentWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:18678:30)
    at workLoop (http://localhost:5173/node_modules/.vite/deps/chunk-J4JQZ5XV.js?v=15f35e51:195:42)

Including svg like

// src/app.tsx line 7
import CustomIcon from './aa.svg?react';

Including svgr in vite config

// vite.main.config.ts

// line 2
import svgr from 'vite-plugin-svgr';

// line 12
plugins: [svgr()],

A minimal repo is here:

https://github.com/zzswang/for-svgr-issue

Any ideas? Thanks

red2678 commented 8 months ago

@zzswang did you figure that out?

zzswang commented 8 months ago

@zzswang did you figure that out?

Sorry, forgot to update it.

Yes, I've fixed it.

How to fix it:

My project is based on electron forge. I move the plugin settings from vite.main.config.ts to vite.renderer.config.ts. Then it works like a charm.

issam-seghir commented 4 months ago

it's work when i use relative path in import , and install @sgvr plugins

npm i -D @svgr/plugin-jsx @svgr/plugin-svgo

My vite config :

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

export default defineConfig({
    base: "/my-app/",
    plugins: [
        [react()],
        svgr({
            // svgr options: https://react-svgr.com/docs/options/
            svgrOptions: {
                plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
                svgoConfig: {
                    plugins: ["preset-default", "removeTitle", "removeDesc", "removeDoctype", "cleanupIds"],
                },
            },
            // A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should include.
            include: "**/*.svg?react",
        }),
    ],
});

My code :

import Logo from "../../../public/logo/logo.svg?react";
...
export default function App() {
return (
            <Logo/>
    );
}