vite-plugin-svg-sprite icon indicating copy to clipboard operation
vite-plugin-svg-sprite copied to clipboard

Vite still outputs SVG assets during build

Open jods4 opened this issue 4 years ago • 7 comments

This plugins works great, but I noticed that when you build, SVG assets that were handled by vite-plugin-svg-sprite are still all copied into the output assets directory, although they're not needed.

Any idea how to avoid that?

jods4 avatar May 11 '21 10:05 jods4

I will take a look

meowtec avatar May 11 '21 10:05 meowtec

FYI I couldn't find a good way to influence Vite or Rollup to modify this. I ended up adding the following hand-made rollup plugin:

{
  name: 'svg-asset-remover',
  generateBundle(_, bundle) {
    // do not emit svg assets as they have been packed by svgPlugin
    for (const file in bundle) {
      if (bundle[file].type === 'asset' && file.endsWith('.svg'))
        delete bundle[file]
    }
  }
}

You could re-use this but instead of removing all files ending with .svg, maybe keep a map of files that have been processed by vite-plugin-svg-sprite during build?

The big defect with this approach is that it potentially could remove an SVG asset that was added another way and was not handled by vite-plugin-svg-sprite... but that's the best idea I could come up with.

jods4 avatar May 11 '21 13:05 jods4

Thank you @jods4! I'm developing an extension for Azure DevOps which doesn't allow svg files for some reason so the fact that they are still being created was a major pain in my back.

@meowtec Would it be possible to get something like what @jods4 suggested into the main plugin? I'm not super knowledgeable in rollup/vite plugins but would be willing to help out on a pull request if needed.

gburning avatar Oct 13 '22 18:10 gburning

@meowtec any movement on this?

jakewhiteley avatar Oct 23 '22 20:10 jakewhiteley

Follow https://github.com/meowtec/vite-plugin-svg-sprite/issues/8#issuecomment-838477976, the code should be like

const transformedFilePaths = new Set<string>();

const plugin: Plugin = {
  name: 'svg-sprite',

  async transform(src, filepath) {
    if (!micromatch.isMatch(filepath, match, {
      dot: true,
    })) {
      return undefined;
    }

    transformedFilePaths.add(filepath);
  },
  generateBundle(_, bundle) {
    for (const file in bundle) {
      // file or bundle[file] can not match transformedFilePaths, they have difference formats
      if (hasTransformed(file, bundle[file]))
        delete bundle[file]
    }
  },
}

There is no good way to detect whether a svg file (the bundle[file]) has been transformed by the plugin.

The item of transformedFilePaths is absolute file path, while bundle[file].name is relative. And can not find the base dir of them.

meowtec avatar Oct 24 '22 03:10 meowtec

Maybe you can try this plugin vite-plugin-svg-icons. This plugin can solve this problem @jods4

AFine970 avatar Jan 12 '23 06:01 AFine970

@AFine970 thanks, I'll keep that plugin in mind. For now everything works ok for me thanks to the clean-up plugin I wrote above.

One thing I like in vite-plugin-svg-sprite is its ability to generate components for icons based on a custom template.

jods4 avatar Jan 12 '23 09:01 jods4