cyyynthia / vite-plugin-magical-svg

An all-in-one Vite plugin that magically makes working with SVGs and bundling them a breeze.
BSD 3-Clause "New" or "Revised" License
46 stars 6 forks source link

During dev, both symbol and use are there in all occurrences/uses of the imported component #17

Open Firsh opened 3 months ago

Firsh commented 3 months ago

Thanks for this, I made it work better than svgr. Although not with dynamic imports, that ended up putting ALL the icons in the sprite.

Is it normal that in dev, each time I use a component, both symbol and use are in the svg tag, leading to duplicate ids? In prod when there is an actual sprite file requested, the symbol tags are correctly gone and only use remains in them, as expected.

import Ban from "@icons/ban.svg";
import Bubble from "@icons/bubble.svg";
            <Ban />
            <Bubble />
            <Bubble />
<svg viewBox="0 0 64 64" width="64" height="64">
<symbol fill="currentColor" version="1.1" id="d41d110e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve" width="64" height="64"><g><g><g><path d="..."></path></g></g></g></symbol>
<use href="#d41d110e"></use>
</svg>
<svg viewBox="0 0 64 64" width="64" height="64">
<symbol fill="currentColor" version="1.1" id="d41d110e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve" width="64" height="64"><g><g><g><path d="..."></path></g></g></g></symbol>
<use href="#d41d110e"></use>
</svg>
magicalSvgPlugin({
      // By default, the output will be a dom element (the <svg> you can use inside the webpage).
      // You can also change the output to react (or any supported target) to get a component you can use.
      target: "react-jsx",

      // By default, the svgs are optimized with svgo. You can disable this by setting this to false.
      svgo: true,

      // By default, width and height set on SVGs are not preserved.
      // Set to true to preserve `width` and `height` on the generated SVG.
      preserveWidthHeight: false,

      // *Experimental* - set the width and height on generated SVGs.
      // If used with `preserveWidthHeight`, will only apply to SVGs without a width/height.
      setWidthHeight: { width: "64", height: "64" },

      // *Experimental* - replace all instances of `fill="..."` and `stroke="..."`.
      // Set to `true` for 'currentColor`, or use a text value to set it to this value.
      // Disabled by default.
      setFillStrokeColor: true,

      // *Experimental* - if a SVG comes with `width` and `height` set but no `viewBox`,
      // assume the viewbox is `0 0 {width} {height}` and add it to the SVG.
      // Disabled by default.
      restoreMissingViewBox: false,
    }),

In dev, I could only reach that behavior by using ?sprite=inline, which for some reason fails to work in prod (the 0 width/height definition is not placed anywhere). For those I had to create an svg.d.ts file btw:

declare module "*.svg?sprite=inline" {
  const content: React.FC<React.SVGProps<SVGSVGElement>>;
  export default content;
}

Have you started SVGSoup? You radiated lots of enthusiasm in the article, I was hoping you wrote it since.

cyyynthia commented 3 months ago

Although not with dynamic imports, that ended up putting ALL the icons in the sprite.

16 might be relevant. So long the icons are treeshaken from the output JS, then they won't be included in the sprite once that's merged.

Is it normal that in dev, each time I use a component, both symbol and use are in the svg tag, leading to duplicate ids?

Yes. This is the easiest, fastest and hmr-friendly way of doing it in dev and has no impact on the behavior of the svg.

In dev, I could only reach that behavior by using ?sprite=inline, which for some reason fails to work in prod

The fact they're broken in prod is bad, I'll give that a look

Have you started SVGSoup? You radiated lots of enthusiasm in the article, I was hoping you wrote it since.

I haven't worked much on it. I initially wanted to but chronic depression decided otherwise 😄🔫

This plugin is still doing a good job so far