Closed cheetahbyte closed 1 year ago
After looking around for a bit and asking a few people this is the wanted behaviour so your assumption that this may not be a bug is correct.
Your provided solution is correct and here is a suggestion:
Create an alias so you don't have to write the full path when importing the icons:
svelte.config.js
:
const config = {
kit: {
adapter: adapter(),
alias: {
$lucide: 'node_modules/lucide-svelte/dist/svelte/icons'
}
}
};
and then reference this in your component (don't forget run npm run dev
again):
<script lang="ts">
import Skull from '$lucide/skull.svelte';
</script>
<Skull />
Hope this helps. @ericfennis I assume this issue can be closed now.
I'm just wondering if bad performance (which is caused by this feature) is actually "wanted behaviour". But thanks for your help and answer, @JanTrichter.
@cheetahbyte this should only take a bit longer during build time. The runtime performance should not be influenced by this.
This issue may does not harm runtime performance, but build performance, which is an important factor. Think about pipelines and ci/cd (like github actions). When you deploy your app to something like vercel or other tools, this "a bit longer" build times can cost real money, that could be saved simply by designing this lib better than it currently is.
I think, I and many others would consider building unnecessary stuff (like unused icons) bad design. And the workaround mentioned here simply is a workaround that should not be common practise or a valid solution to this issue.
I would like to mention https://github.com/lucide-icons/lucide/issues/1403 which does seem to suffer from the same issue and demonstrates why this definitly is an issue and should be addressed.
I agree with @DreamTexX
@DreamTexX PRs or suggestions how to fix this are absolutely welcome, maybe the real money motivates someone 😄
I want to clarify the confusion that all icons are bundled when an application is built. That's not, but all icons are "transformed" during build, this because the library ships Svelte component files.
To be clear lucide-svelte
is completely tree-shakable.
Here a screenshot of a visualizer of a project with one imported icon.
however, @DreamTexX is right. The problem that we encounter is all the way how Svelte components are transpiled/transformed in Vite. If it sees an ".svelte" extension the Vite will transform this first to JS before it starts the tree-shaking process. That results in unnecessary transpilation and transformation. This something Vite and Svelte could improve, see issue https://github.com/vitejs/vite/issues/8237
So the solution for this can be pre-transforming Svelte components, shipping JS modules instead of Svelte components. This is something that we did before. But this led to some issues in SvelteKit see #833, this is because SvelteKit uses different preprocessing for client-side and SSR, and the pre-transformed lucide icons didn't work in SSR. So we switched to Svelte components instead. There is a possibility that since we had this issue with SvelteKit, the Svelte team solved it in the latest versions of the Svelte Preprocessor (the transformer of the Svelte files). So this is something we can check en test.
I've also looked at other frameworks and libraries but everyone is doing it differently. So not sure what the "way" is of shipping a Svelte component library: Pre-transformed or Svelte Components.
Would be nice if a Svelte expert can give me some info on this!
What if the API is changed slightly to import icons from lucide-svelte/<IconName>
(if this is possible somehow) instead of a single big index file?
@DreamTexX See the first answer which is basically doing this.
The first answer still is a kind of hacky workaround, i talk about using official ways like using this feature: https://kit.svelte.dev/docs/packaging#anatomy-of-a-package-json-exports
"exports": {
"./SomeIcon.svelte": {
"svelte": "path/to/icons/SomeIcon.svelte"
}
}
This would have to be generated obviously. But this is just a suggestion based of some googeling.
@DreamTexX Yeah this maybe a good in-between solution to keep performance. I will work on this!
This is still happening in my case with 0.275.0-beta.0
. I'm not sure if I'm using the imports correctly (see my comment on #1284).
Using the workaround proposed by @cheetahbyte does not work with versions later than 0.263.0 in sveltekit.
After #1499, the path to directly import icons is:
import VideoIcon from 'lucide-svelte/icons/video'
This works for me and avoids the excessively slow compile. (Of course, replace Video
/video
with the name of the icon you need.)
This should now be listed in the README as the recommended way, and import { VideoIcon } from 'lucide-svelte'
should be warned against in the README.
hate to +1 one this guy, but the fact I'm seeing 7mb+ of icons in my development app when I'm using 10 icons is harshing my vibes
i get there are probably reasons for this, but slowing down my dev process so I can use some SVGs is kinda frustrating
it does seem Tabler also has this issue, so i guess Lucide is not alone:
https://github.com/tabler/tabler-icons/issues/669
EDIT: unless I'm crazy, shouldn't you not be using barrel files?
I wanted to bring up something that has been on my mind for a little while, when I import an icon from lucide-svelte and build my sveltekit project, all 1221 icons are directly bundled with it. This results in build times of about 30 seconds (on my machine).
To be honest, I am not sure if this can be considered a "bug".
The workaround I found is to import the file directly from it's "source".
Step to reproduce
+page.svelte
inside your terminal
Workaround
+page.svelte
inside your terminal
Resources
Without Workaround
With Workaround