poppa / sveltekit-svg

SvelteKit plugin that makes it possible to import SVG files as Svelte components, inline SVG code or urls
MIT License
221 stars 22 forks source link

`?url` + SVGO? #52

Open aradalvand opened 7 months ago

aradalvand commented 7 months ago

Hey there! I have a scenario where I need to import an SVG file as a URL (rather than as a Svelte component), but I still want it to go through SVGO. Unfortunately, using the ?url option seems to cause SVGO to be bypassed. Is there a way around this? And wouldn't it make more sense in general to have all SVGs go through SVGO regardless of how they're imported? That's certainly what I was expecting.

poppa commented 7 months ago

Hi @aradalvand!

Well, that really makes no sense for this type of plugin. Rememeber, this is not a runtime plugin, but a compile time one.

Just use SVGO itself directly to preprocess your SVG:s 👍

aradalvand commented 7 months ago

Rememeber, this is not a runtime plugin, but a compile time one.

@poppa Not sure how that means this wouldn't make sense?! I'm very much referring to compile-time SVGO processing.

Currently, this goes through SVGO:

<script>
    import someSvg from './some.svg?dataurl';
</script>

But this doesn't:

<script>
    import someSvg from './some.svg?url';
</script>

I don't think it's unreasonable to suggest that this asymmetry could be undesirable.

poppa commented 7 months ago

We'll, there's a fundamental difference between the two: The former is compiled into a string in the resulting JS, the latter is read as an URL runtime by the browser.They are not even remotley the same.

So, the former is used compile time, the latter runtime.

What you are asking for is exactly what SVGO already does. Use SVGO in your build process to generate optimized SVGs on disk.

aradalvand commented 7 months ago

the latter is read as an URL runtime by the browser.

Vite processes it during the build step, so it's not just handed over to the browser as is; couldn't this plugin hook into Vite's build step and ask Vite to give it any SVG files it encounters?

poppa commented 7 months ago

That would mean that this plugin would have to overwrite the source SVG on disk, and that is NOT what this plugin should do. Simply run npx svgo path/to/file.svg instead.

aradalvand commented 7 months ago

... this plugin would have to overwrite the source SVG on disk

That's definitely not what I'm suggesting. There might be something I'm missing here because this seems obvious to me. In SvelteKit, you run npm run build to generate build artifacts inside some directory, Vite processes all the source files (including SVG source files) and generates "build copies" of them that are, for example, minified, and so on. It does this with the help of plugins, if there are any.

When Vite is generating, say icon.b1946ac9.svg (from the source file icon.svg) during the build process, can't this plugin hook into that and process that SVG file before its build copy is written to disk?

poppa commented 7 months ago

I'm more than happy to accept a pull request.

aradalvand commented 7 months ago

@poppa I'm not sure why you closed the issue?! You eventually acknowledged that this is doable and that you'd be "more than happy to accept a pull request"; no?

poppa commented 6 months ago

Hopefully this should now work in v4.2.0. Try and see if it works as expected 👍

aradalvand commented 6 months ago

@poppa This does seem to be working in 4.2.0. Thank you!

One small thing though: the hash that Vite appends to the filename seems to be based on the non-SVGO'ed of the SVG; but it should actually be based on the SVGO'ed SVG instead, because currently changing the SVGO configurations (which might result in a different final SVG) doesn't result in a new hash and by extension doesn't allow cache busting to occur. I think this needs to be corrected; but other than that, it's great, thanks again for implementing this.

aradalvand commented 6 months ago

One more thing: This doesn't seem to work for .css/.scss files processed by Vite that reference SVGs, for example:

.whatever {
    background-image: url('$lib/icons/some-icon.svg?url');
}

I was hoping this would work (as in it would run the linked SVG through SVGO when generating build artifacts). Is this expected?